Opera function visibility oddity

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • phil_gg04@treefic.com

    Opera function visibility oddity

    Dear Javascript Experts,

    Opera seems to have different ideas about the visibility of Javascript
    functions than other browsers. For example, if I have this code:

    if (1==2) {
    function invisible() {
    alert("invisibl e() called");
    }
    }

    then most browsers will consider invisible() to be undefined. But in
    Opera you can call it! You can try this online here:
    http://chezphil.org/bugreps/funcdecl.html - with most browsers you'll
    get an error (open your javascript console) but Opera will show the
    alert.

    So: is this an Opera bug, or is either behaviour acceptable? (I'd be
    interested to know what Safari and any other less-common browsers do.)

    --Phil.

  • Random

    #2
    Re: Opera function visibility oddity

    I wouldn't call this a bug-- it's why we can define functions at the
    bottom of our script, or in the middle, or all over the place, and use
    them anywhere. It's expected that function definitions using the
    function statement will work regardless of where you put them. I've
    actually had the same experience with IE (Win32).

    If you really don't want that function defined except in certain
    circumstances, try something like this:

    if( foo )
    bar = function ( arg1, arg2 ) {
    // statements
    }

    Alternatively, you may use the Function constructor, but that can be
    somewhat ponderous.


    phil_g...@treef ic.com wrote:[color=blue]
    > Dear Javascript Experts,
    >
    > Opera seems to have different ideas about the visibility of[/color]
    Javascript[color=blue]
    > functions than other browsers. For example, if I have this code:
    >
    > if (1==2) {
    > function invisible() {
    > alert("invisibl e() called");
    > }
    > }
    >
    > then most browsers will consider invisible() to be undefined. But in
    > Opera you can call it! You can try this online here:
    > http://chezphil.org/bugreps/funcdecl.html - with most browsers you'll
    > get an error (open your javascript console) but Opera will show the
    > alert.
    >
    > So: is this an Opera bug, or is either behaviour acceptable? (I'd be
    > interested to know what Safari and any other less-common browsers[/color]
    do.)[color=blue]
    >
    > --Phil.[/color]

    Comment

    • Michael Winter

      #3
      Re: Opera function visibility oddity

      On 24/05/2005 12:22, phil_gg04@treef ic.com wrote:

      [snip]
      [color=blue]
      > if (1==2) {
      > function invisible() {
      > alert("invisibl e() called");
      > }
      > }[/color]

      This is a syntax error. I imagine it is not flagged because it is
      considered too common, and will break too many scripts. However, it is a
      mistake and should never occur within a script.


      There are three ways to create a function object in ECMAScript: the
      function declaration, the function expression, and the Function
      constructor function.

      The first, the function declaration, is fairly simple and recognisable:

      function <identifier> ( <argument list> ) {
      <function body>
      }

      What is not always appreciated is that function declarations can only
      appear in two general locations: at the program (aka root, or global)
      level, and within the function body of another function. So,

      /* Program */
      function myFunction() {
      }

      and

      /* Program */
      function myOuterFunction () {

      /* Function body */
      function myInnerFunction () {
      }

      }

      are fine. However,

      if(condition) {

      /* Statement list */
      function myFunction() {
      }

      }

      is not because statements like if and while expect other statements.

      Function declarations are somewhat special. Unlike most source elements,
      they are evaluated before execution would normally reach them. This is
      why you can call a function before you have defined it.

      When a script is initially parsed, all function declarations at the
      program level will be evaluated, and the corresponding function objects
      will be created. It is only after this process that execution begins.
      Similarly, when a function is called, any inner function declarations
      (such as myInnerFunction , above) are evaluated before execution of that
      function commences.


      The second, the function expression, is a little awkward to explain,
      mainly because it might be difficult to see the distinction with
      function declarations. Essentially, a function expression works like any
      other expression: it is not evaluated until execution reaches it. This
      allows you to create functions conditionally:

      var func;

      if(condition) {

      func = function( <argument list> ) {
      <function body>
      };

      }

      Only if condition is true will the expression be evaluated. If condition
      is false, func will remain undefined.

      So, how /do/ you distinguish between a function expression and a
      declarations? Essentially, it depends on the beginning of a source
      element. If it starts with a 'function' token, it is a declaration. If
      it starts with something else, it's a function expression. For example,

      (function() {
      /* ... */
      })();

      is a function expression because the source element begins with an
      opening parenthesis.

      A function expression can still have an identifier

      func = function <identifier>( <argument list> ) {
      <function body>
      };

      but this is only so the function can refer to itself - for recursion,
      for example. It's not to be used outside of the function body.


      I'll ignore the Function constructor for now. I'm sure the above is more
      than enough information. What I will say is that although the Function
      constructor can be used to create function objects at runtime like
      function expressions, there are major differences between the two.

      [snip]

      If something needs more explanation, please ask.

      Mike

      --
      Michael Winter
      Replace ".invalid" with ".uk" to reply by e-mail.

      Comment

      • Hallvord R. M. Steen

        #4
        Re: Opera function visibility oddity

        > Opera seems to have different ideas about the visibility of Javascript[color=blue]
        > functions than other browsers. For example, if I have this code:
        >
        > if (1==2) {
        > function invisible() {
        > alert("invisibl e() called");
        > }
        > }
        >
        > then most browsers will consider invisible() to be undefined. But in
        > Opera you can call it![/color]

        This behaviour is by design.

        If you want function definition to depend on an if clause, do the following

        if (1==2) {
        var invisible = function () {
        alert("invisibl e() called");
        }
        }


        --
        Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

        Comment

        • phil_gg04@treefic.com

          #5
          Re: Opera function visibility oddity

          I wrote:[color=blue][color=green]
          >> if (1==2) {
          >> function invisible() {
          >> alert("invisibl e() called");
          >> }
          >> }[/color][/color]

          Mike Winter replied:[color=blue]
          > This is a syntax error
          > [snip lots of useful explanation][/color]

          Thanks Mike. I had just started to look it up in the Ecma
          specification and was coming to the same conclusion.

          I had come across this in the following context:

          if (detect_some_br owser) {
          ... declare functions for that browser ...
          } else if (detect_some_ot her_browser) {
          ... declare function for that other browser ...
          }

          and it took a long time to understand why Opera was executing the
          special IE versions of the functions, rather than the "all other
          browser" ones.

          Ideally, of course, all browsers would reject this with an error
          message. I encourage Opera to either do what the other browsers do
          (the pragmatic approach) or to reject it with an error message (the
          purist approach). What they currently do, i.e. accept the invalid code
          but interpret it differently from the other browsers, is confusing.

          --Phil.

          Comment

          • Michael Winter

            #6
            Re: Opera function visibility oddity

            On 24/05/2005 14:36, phil_gg04@treef ic.com wrote:

            [snip]
            [color=blue]
            > if (detect_some_br owser) {[/color]

            Browser detection is flawed. Instead, you should be examining the
            capabilities of any particular host. For example, Opera supports quite
            of few of Microsoft's proprietary capabilities, as well as those defined
            by the W3C.

            See the browser detection entry in the group FAQ, and the related
            article in the FAQ notes.

            [snip]

            Mike

            --
            Michael Winter
            Replace ".invalid" with ".uk" to reply by e-mail.

            Comment

            Working...