Could you tell me why ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jorge

    Could you tell me why ?

    <html><head></head><body><scr ipt>

    (function () {
    var watch = "Hola !";
    (function f () { alert(watch) })();
    alert(typeof f);
    })();

    </script></body></html>

    This yields:

    Safari : "Hola !", "undefined" .
    FireFox : "function () watch { [native code] }", "undefined"

    Could you (kindly, please) tell me why :

    1.- FF turns watch into a native function.
    2.- f remains undefined.

    TIA,
    --Jorge.
  • Henry

    #2
    Re: Could you tell me why ?

    On May 7, 10:19 am, Jorge wrote:
    <html><head></head><body><scr ipt>
    >
    (function () {
    var watch = "Hola !";
    (function f () { alert(watch) })();
    alert(typeof f);
    >
    })();
    >
    </script></body></html>
    >
    This yields:
    >
    Safari : "Hola !", "undefined" .
    FireFox : "function () watch { [native code] }", "undefined"
    >
    Could you (kindly, please) tell me why :
    >
    1.- FF turns watch into a native function.
    2.- f remains undefined.
    JavaScript(tm) objects have - watch - and - unwatch - methods (as an
    aid to debugging). When a Function Expression is provided with the
    optional Identifier (your 'f' in this case) the specified behaviour is
    to create the corresponding function object with an additional object
    at the top of the scope chain that is referred to by the function's
    internal [[Scope]] property and give that object a name which
    corresponds with the Identifier and a value that refers to the
    function object. A side effect of this is that when the function is
    executed it has an ordinary javascript object on its scope chain and
    so all Identifiers used within the function that correspond with the
    named properties of ordinary javascript objects will resolve as
    properties of that particular object if not masked by formal
    parameter, local variable or inner function declarations. And where
    the ordinary javascript object have a - watch - property (such as in
    JavaScript(tm)) then the Identifier - watch - will resolve as a
    reference to the -watch - method of that object.

    f "remains undefined" because the FunctionExpress ion with optional
    Identifier does not result in the creation of a named property of the
    Activation/Variable object for the execution context in which it is
    evaluated (it is not a FunctionDeclara tion, which would). That is
    until you try this in IE and see the bug that makes using the optional
    Identifiers with FunctionExpress ions such a bad idea that you would be
    best off never attempting it.

    Comment

    • Jorge

      #3
      Re: Could you tell me why ?

      On May 7, 12:46 pm, Henry <rcornf...@rain drop.co.ukwrote :
      JavaScript(tm) objects have - watch - and - unwatch - methods (as an
      aid to debugging). When a Function Expression is provided with the
      optional Identifier (your 'f' in this case) the specified behaviour is
      to create the corresponding function object with an additional object
      at the top of the scope chain that is referred to by the function's
      internal [[Scope]] property and give that object a name which
      corresponds with the Identifier and a value that refers to the
      function object. A side effect of this is that when the function is
      executed it has an ordinary javascript object on its scope chain and
      so all Identifiers used within the function that correspond with the
      named properties of ordinary javascript objects will resolve as
      properties of that particular object if not masked by formal
      parameter, local variable or inner function declarations. And where
      the ordinary javascript object have a - watch - property (such as in
      JavaScript(tm)) then the Identifier - watch - will resolve as a
      reference to the -watch - method of that object.
      Ahh.., so there was beforehand a .watch() method... !
      But not in Safari... etc right ?
      Only in FireFox ?
      And, is that method a part of the standard ?
      Why do you write ***JavaScript(t m)*** ?
      f "remains undefined" because the FunctionExpress ion with optional
      Identifier does not result in the creation of a named property of the
      Activation/Variable object for the execution context in which it is
      evaluated (it is not a FunctionDeclara tion, which would). That is
      until you try this in IE and see the bug that makes using the optional
      Identifiers with FunctionExpress ions such a bad idea that you would be
      best off never attempting it.
      Hmm, I was expecting (function funcName () {})(); to yield a defined
      funcName in that context.
      Why is that a bad idea ?
      You could always have used an unnamed function instead, I mean, if you
      didn't intend to get funcName defined... ?

      (function () {
      var watch = aVar = "Hola !";
      (function f () {
      alert(aVar);
      alert(watch);
      alert(typeof f);
      })();
      alert(typeof f);
      })();

      IE8b : "Hola !", "Hola !", "function", "function" <- You're right,
      IE did it !
      Safari : "Hola !", "Hola !", "function", "undefined"
      FireFox : "Hola !", "native function ()", "function", "undefined"

      Thanks for sharing,
      --Jorge.

      Comment

      • Henry

        #4
        Re: Could you tell me why ?

        On May 7, 12:28 pm, Jorge wrote:
        On May 7, 12:46 pm, Henry wrote:
        >JavaScript(t m) objects have - watch - and - unwatch - methods ...
        <snip>
        Ahh.., so there was beforehand a .watch() method... !
        Yes.
        But not in Safari... etc right ?
        Not yet, but Safari could add one at any moment. Opera's ECMAScript
        implementation has - watch - and unwatch - methods on its object for
        compatibility with JavaScript(tm), and Safari does do some things for
        similar compatibility.
        Only in FireFox ?
        Not only (and that is assuming that "FireFox" is taken to mean all
        Mozilla/Gecko based web browsers (and there are 20 odd of them by
        now).
        And, is that method a part of the standard ?
        No. But the standard allows implementations to provide extensions and
        those methods are an extension.
        Why do you write ***JavaScript(t m)*** ?
        JavaScript, with an uppercase J and an upper case S, is the trademark
        name of what is now a single ECMAScript implementation (the one that
        originated at Netscape, is now the responsibility of the Mozilla
        foundation and appears in Firefox/Mozilla/Gecko browsers). There are
        numerous other ECMAScript implementations , such as JScript(tm) in IE
        browsers. I tend to use 'javascript' or 'Javascript' (with the non-
        trademark capitalisation) to refer to geniality of ECMAScript
        implementations (as do many others) and the trademark names to refer
        to the specific implementations unambiguously (especially with the
        "(tm)" extension) (were they have such names (and I know what those
        names are)).
        >f "remains undefined" because the FunctionExpress ion with
        >optional Identifier does not result in the creation of a
        >named property of the Activation/Variable object for the
        >execution context in which it is evaluated (it is not a
        >FunctionDeclar ation, which would). That is until you try
        >this in IE and see the bug that makes using the optional
        >Identifiers with FunctionExpress ions such a bad idea that
        >you would be best off never attempting it.
        >
        Hmm, I was expecting (function funcName () {})(); to yield a defined
        funcName in that context.
        But the specification says that should not happen. FunctionExpress ions
        and FunctionDeclara tions are not handled the same way regardless of
        how similar they may appear in some cases.
        Why is that a bad idea ?
        Which? Thinking it should create a named property of the variable
        object or using the optional Identifiers with FunctionExpress ions? The
        former is a bad idea because it is at odds with the specification and
        the reality of most implementations of that specification. The latter
        is a bad idea because IE does not conform to the specification in this
        area and what it does do is sufficiently strange as to be
        problematic.
        You could always have used an unnamed function instead,
        I mean, if you didn't intend to get funcName defined... ?
        The use of the optional Identifier with FunctionExpress ions is to
        allow code inside the function body to refer to the function object by
        name (rather than using - arguments.calle e -).
        (function () {
        var watch = aVar = "Hola !";
        (function f () {
        alert(aVar);
        alert(watch);
        alert(typeof f);
        })();
        alert(typeof f);
        ^^^^^^^^^^^^^^
        Try moving this line to above the evaluation of the function
        expression to see how badly IE is behaving here.
        >
        })();
        >
        IE8b : "Hola !", "Hola !", "function", "function" <- You're right,
        IE did it !
        <snip>
        Yes, and if you it you would discover that the function object that
        results form the evaluation of the function expression is not the same
        function object as can be referred to using the Identifier in the
        containing context.

        Comment

        • Jorge

          #5
          Re: Could you tell me why ?

          On May 7, 2:27 pm, Henry <rcornf...@rain drop.co.ukwrote :
          On May 7, 12:28 pm, Jorge wrote:
          >
          On May 7, 12:46 pm, Henry wrote:
          JavaScript(tm) objects have - watch - and - unwatch - methods ...
          <snip>
          Ahh.., so there was beforehand a .watch() method... !
          >
          Yes.
          >
          But not in Safari... etc right ?
          >
          Not yet, but Safari could add one at any moment. Opera's ECMAScript
          implementation has - watch - and unwatch - methods on its object for
          compatibility with JavaScript(tm), and Safari does do some things for
          similar compatibility.
          >
          Only in FireFox ?
          >
          Not only (and that is assuming that "FireFox" is taken to mean all
          Mozilla/Gecko based web browsers (and there are 20 odd of them by
          now).
          >
          I see. But Opera behaves the same as Safari.
          FF3 behaves as FF2, but it's JS is not spiderMonkey, isn't it ?
          The other spiderMonkeys I've tested all behave as FF2.

          --Jorge.

          Comment

          • Jorge

            #6
            Re: Could you tell me why ?

            On May 7, 2:27 pm, Henry <rcornf...@rain drop.co.ukwrote :
            On May 7, 12:28 pm, Jorge wrote:
            >
            Hmm, I was expecting (function funcName () {})(); to yield a defined
            funcName in that context.
            >
            But the specification says that should not happen. FunctionExpress ions
            and FunctionDeclara tions are not handled the same way regardless of
            how similar they may appear in some cases.
            >
            Why is that a bad idea ?
            >
            Which? Thinking it should create a named property of the variable
            object or using the optional Identifiers with FunctionExpress ions? The
            former is a bad idea because it is at odds with the specification and
            the reality of most implementations of that specification. The latter
            is a bad idea because IE does not conform to the specification in this
            area and what it does do is sufficiently strange as to be
            problematic.
            >
            You could always have used an unnamed function instead,
            I mean, if you didn't intend to get funcName defined... ?
            >
            The use of the optional Identifier with FunctionExpress ions is to
            allow code inside the function body to refer to the function object by
            name (rather than using - arguments.calle e -).
            >
            (function () {
             var watch = aVar = "Hola !";
             (function f () {
              alert(aVar);
              alert(watch);
              alert(typeof f);
              })();
             alert(typeof f);
            >
               ^^^^^^^^^^^^^^
            Try moving this line to above the evaluation of the function
            expression to see how badly IE is behaving here.
            >
            >
            >
            })();
            >
            IE8b    : "Hola !", "Hola !", "function", "function" <- You're right,
            IE did it !
            >
            <snip>
            Yes, and if you it you would discover that the function object that
            results form the evaluation of the function expression is not the same
            function object as can be referred to using the Identifier in the
            containing context.
            Ok :

            <html><head></head><body><scr ipt>

            (function () {
            var f2, watch = aVar = "Hola !",
            d = function (p) { document.write( p) },
            n = "<br>";

            d("typeof f: "+(typeof f)+n);
            d(n+"Entering f..."+n+n);
            f2 = (function f () {
            d("aVar: "+aVar+n);
            d("watch: "+watch+n);
            d("typeof f: "+(typeof f)+n);
            d("(f === arguments.calle e): "+(f === arguments.calle e)+n);
            return arguments.calle e;
            })();
            d(n+"Leaving f..."+n+n);
            d("typeof f: "+(typeof f)+n);
            d("typeof f2: "+(typeof f2)+n+"f2 === f: ");
            try { d((f2 === f)+n) } catch (e) {
            d("throws an exception"+n); }
            })();

            </script></body></html>

            *************** IE5 Mac :
            typeof f: function
            Entering f...
            aVar: Hola !
            watch: Hola !
            typeof f: function
            (f === arguments.calle e): true
            Leaving f...
            typeof f: function
            typeof f2: function
            f2 === f: true <-- Yeah !

            *************** IE8b Win :
            typeof f: function

            Entering f...

            aVar: Hola !
            watch: Hola !
            typeof f: function
            (f === arguments.calle e): false <-- What ?

            Leaving f...

            typeof f: function
            typeof f2: function
            f2 === f: false <-- What you said (weird !)

            *************** Safari, Opera : Win & Mac :
            typeof f: undefined

            Entering f...

            aVar: Hola !
            watch: Hola !
            typeof f: function
            (f === arguments.calle e): true

            Leaving f...

            typeof f: undefined
            typeof f2: function
            (f2 === f) throws an exception

            *************** SpiderMonkeys : FF2, Camino, SeaMonkey, NS9...
            typeof f: undefined

            Entering f...

            aVar: Hola !
            watch: function watch() { [native code] }
            typeof f: function
            (f === arguments.calle e): true

            Leaving f...

            typeof f: undefined
            typeof f2: function
            (f2 === f) throws an exception

            *************** FF3.0pre : "MineField" :
            typeof f: undefined

            Entering f...

            aVar: Hola !
            watch: function watch() { [native code] }
            typeof f: function
            (f === arguments.calle e): true

            Leaving f...

            typeof f: undefined
            typeof f2: function
            (f2 === f) throws an exception

            *************** ***************

            -IE5Mac did what I was expecting... (!)
            -IE8b does weird things : f !== arguments.calle e, f2 !== f... !
            -Safari as Opera.
            -Mozillas : all equal.

            --Jorge.

            Comment

            • Henry

              #7
              Re: Could you tell me why ?

              On May 7, 9:12 pm, Jorge wrote:
              On May 7, 2:27 pm, Henry wrote:
              <snip>
              -IE5Mac did what I was expecting... (!)
              Expect it as you may, it is still objectively incorrect behaviour for
              an ECMAScript implementation (a bug).
              -IE8b does weird things : f !== arguments.calle e, f2 !== f... !
              Yes, two function objects and if the one that results form the
              function expression attempts to call itself using its name it will
              actually call the other function object.
              -Safari as Opera.
              There remain two possible explanations of not resolving the - watch -
              identifier on the object added to the innermost function's scope
              chain. One is that the native objects don't have - watch - method
              (which is allowed/normal) and the other is that the object added to
              the scope chain was not a (normal) native object (which is incorrect
              and so would be an implementation bug). Testing the latter might
              involve declaring something like a - toString - variable in the
              containing function and seeing how a - toString - identifier is
              resolved from the inner function (as all native objects have toString
              methods).
              -Mozillas : all equal.
              Hence the general advice not to use the optional Identifiers with
              FunctionExpress ions. There are so many (different) implementation bugs
              that expecting any particular behaviour when using them is not
              practical.

              Comment

              • Jorge

                #8
                Re: Could you tell me why ?

                On May 8, 12:19 pm, Henry <rcornf...@rain drop.co.ukwrote :
                On May 7, 9:12 pm, Jorge wrote:
                >
                On May 7, 2:27 pm, Henry wrote:
                <snip>
                -IE5Mac did what I was expecting... (!)
                >
                Expect it as you may, it is still objectively incorrect behaviour for
                an ECMAScript implementation (a bug).
                >
                -IE8b does weird things : f !== arguments.calle e, f2 !== f... !
                >
                Yes, two function objects and if the one that results form the
                function expression attempts to call itself using its name it will
                actually call the other function object.
                >
                Not sure exactly what do you mean ?
                Yet another one more IE bug ?
                Because I see no more weird things here :

                *********** IE5 Mac
                .typeof f: function
                .(f === arguments.calle e.1): true

                ..(f === arguments.calle e): true
                ..(arguments.ca llee.1 === arguments.calle e.2): true

                *********** IE8b Win
                .typeof f: function
                .(f === arguments.calle e.1): false

                ..(f === arguments.calle e): true
                ..(arguments.ca llee.1 === arguments.calle e.2): false

                *****

                <html><head></head><body><scr ipt>

                (function () {
                var n = "<br>", d = function (p){ document.write( p+n) };

                (function f () {
                var a = arguments;
                if (a.length) {
                d(n+"..(f === arguments.calle e): "+(a[0] === a.callee));
                d("..(arguments .callee.1 === arguments.calle e.2): "+(a[1] ===
                a.callee));
                } else {
                d(".typeof f: "+(typeof f));
                d(".(f === arguments.calle e.1): "+(f === a.callee));
                f(f, a.callee);
                }
                })();
                })();

                </script></body></html>

                Thanks,
                --Jorge.

                Comment

                • Henry

                  #9
                  Re: Could you tell me why ?

                  On May 8, 4:02 pm, Jorge wrote:
                  On May 8, 12:19 pm, Henry wrote:
                  >On May 7, 9:12 pm, Jorge wrote:
                  >>-IE5Mac did what I was expecting... (!)
                  >
                  >Expect it as you may, it is still objectively incorrect behaviour for
                  >an ECMAScript implementation (a bug).
                  >
                  >>-IE8b does weird things : f !== arguments.calle e, f2 !== f... !
                  >
                  >Yes, two function objects and if the one that results form the
                  >function expression attempts to call itself using its name it will
                  >actually call the other function object.
                  >
                  Not sure exactly what do you mean ?
                  I mean precisely what I wrote.
                  Yet another one more IE bug ?
                  Because I see no more weird things here :
                  >
                  *********** IE5 Mac
                  .typeof f: function
                  .(f === arguments.calle e.1): true
                  >
                  ..(f === arguments.calle e): true
                  ..(arguments.ca llee.1 === arguments.calle e.2): true
                  >
                  *********** IE8b Win
                  .typeof f: function
                  .(f === arguments.calle e.1): false
                  >
                  ..(f === arguments.calle e): true
                  ..(arguments.ca llee.1 === arguments.calle e.2): false
                  >
                  *****
                  <snip>
                  I see that when the function object that resulted from the
                  FunctionExpress ion attempted to call itself by name in Windows IE it
                  actually ended up calling a different function, which is precisely
                  what I described.

                  Comment

                  • Jorge

                    #10
                    Re: Could you tell me why ?

                    On May 8, 12:19 pm, Henry <rcornf...@rain drop.co.ukwrote :
                    On May 7, 9:12 pm, Jorge wrote:
                    -Safari as Opera.
                    >
                    There remain two possible explanations of not resolving the - watch -
                    identifier on the object added to the innermost function's scope
                    chain. One is that the native objects don't have - watch - method
                    (which is allowed/normal) and the other is that the object added to
                    the scope chain was not a (normal) native object (which is incorrect
                    and so would be an implementation bug). Testing the latter might
                    involve declaring something like a - toString - variable in the
                    containing function and seeing how a - toString - identifier is
                    resolved from the inner function (as all native objects have toString
                    methods).
                    >
                    See, I found no watches in the Opera... :-)

                    DOM object : window.watch :
                    javascript:aler t(typeof window.watch)
                    Safari, Opera : undefined, FF : function

                    DOM.method.watc h :
                    javascript:aler t(typeof alert.watch)
                    Safari, Opera : undefined, FF : function

                    regular function.watch :
                    javascript:(fun ction(){alert(t ypeof arguments.calle e.watch)})()
                    javascript:aler t(typeof (new Function().watc h))
                    javascript:aler t(typeof (function(){}). watch)
                    Safari, Opera : undefined, FF : function

                    regular object.watch :
                    javascript:aler t(typeof (new Object()).watch )
                    javascript:aler t(typeof {}.watch)
                    Safari, Opera : undefined, FF : function

                    JCore native Function constructor watch :
                    javascript:aler t(typeof Function.watch)
                    Safari, Opera : undefined, FF : function

                    Thanks,
                    --Jorge.

                    Comment

                    • Jorge

                      #11
                      Re: Could you tell me why ?

                      On May 8, 5:19 pm, Henry <rcornf...@rain drop.co.ukwrote :
                      On May 8, 4:02 pm, Jorge wrote:
                      <snip>
                      I see that when the function object that resulted from the
                      FunctionExpress ion attempted to call itself by name in Windows IE it
                      actually ended up calling a different function, which is precisely
                      what I described.
                      I couldn't find weird that a call to f() !== a call to
                      arguments.calle e(),
                      because we already knew that f !== arguments.calle e on the first
                      entry... ?

                      But I get what you mean.

                      Thanks,
                      --Jorge.

                      Comment

                      • Thomas 'PointedEars' Lahn

                        #12
                        Re: Could you tell me why ?

                        Jorge wrote:
                        On May 8, 12:19 pm, Henry <rcornf...@rain drop.co.ukwrote :
                        >On May 7, 9:12 pm, Jorge wrote:
                        >>-Safari as Opera.
                        >There remain two possible explanations of not resolving the - watch -
                        >identifier on the object added to the innermost function's scope chain.
                        >One is that the native objects don't have - watch - method (which is
                        >allowed/normal) and the other is that the object added to the scope
                        >chain was not a (normal) native object (which is incorrect and so would
                        >be an implementation bug).
                        Considering Section 2, on what part of the Specification do you base your
                        assessment?
                        >Testing the latter might involve declaring something like a - toString
                        >- variable in the containing function and seeing how a - toString -
                        >identifier is resolved from the inner function (as all native objects
                        >have toString methods).
                        >
                        See, I found no watches in the Opera... :-)
                        *g*
                        DOM object : window.watch : javascript:aler t(typeof window.watch) Safari,
                        Opera : undefined, FF : function
                        >
                        DOM.method.watc h : javascript:aler t(typeof alert.watch) Safari, Opera :
                        undefined, FF : function
                        >
                        regular function.watch : javascript:(fun ction(){alert(t ypeof
                        arguments.calle e.watch)})() javascript:aler t(typeof (new
                        Function().watc h)) javascript:aler t(typeof (function(){}). watch) Safari,
                        Opera : undefined, FF : function
                        >
                        regular object.watch : javascript:aler t(typeof (new Object()).watch )
                        javascript:aler t(typeof {}.watch) Safari, Opera : undefined, FF :
                        function
                        >
                        JCore native Function constructor watch :
                        What is JCore?
                        javascript:aler t(typeof Function.watch) Safari, Opera : undefined, FF :
                        function
                        In the Gecko AOM/DOM, some host objects inherit from the object referred to
                        by JavaScript's Object.prototyp e, which provides the watch() method there.

                        // true
                        window.__proto_ _.__proto__.__p roto__ === Object.prototyp e

                        The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps.



                        PointedEars
                        --
                        Prototype.js was written by people who don't know javascript for people
                        who don't know javascript. People who don't know javascript are not
                        the best source of advice on designing systems that use javascript.
                        -- Richard Cornford, cljs, <f806at$ail$1$8 300dec7@news.de mon.co.uk>

                        Comment

                        • Henry

                          #13
                          Re: Could you tell me why ?

                          On May 8, 5:10 pm, Thomas 'PointedEars' Lahn wrote:
                          >On May 8, 12:19 pm, Henry wrote:
                          <snip>
                          >>One is that the native objects don't have - watch - method (which
                          >>is allowed/normal) and the other is that the object added to the
                          >>scope chain was not a (normal) native object (which is incorrect
                          >>and so would be an implementation bug).
                          >
                          Considering Section 2, on what part of the Specification do you
                          base your assessment?
                          <snip>

                          Section 13; the first step in the algorithm for "FunctionExpres sion :
                          function Identifier ( FormalParameter List<opt) { FunctionBody}". The
                          object added to the scope chain should be an object created "as if by
                          the expression new Object()"; a (normal) native object, including any
                          extension method that would appear on any other object created with
                          new Object().

                          Comment

                          Working...