Opera function visibility oddity

Discussion in 'Javascript' started by phil_gg04@treefic.com, May 24, 2005.

  1. Guest

    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("invisible() 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.
    , May 24, 2005
    #1
    1. Advertising

  2. Random Guest

    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.


    wrote:
    > 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("invisible() 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, May 24, 2005
    #2
    1. Advertising

  3. On 24/05/2005 12:22, wrote:

    [snip]

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


    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.
    Michael Winter, May 24, 2005
    #3
  4. > 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("invisible() called");
    > }
    > }
    >
    > then most browsers will consider invisible() to be undefined. But in
    > Opera you can call it!


    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("invisible() called");
    }
    }


    --
    Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
    Hallvord R. M. Steen, May 24, 2005
    #4
  5. Guest

    I wrote:
    >> if (1==2) {
    >> function invisible() {
    >> alert("invisible() called");
    >> }
    >> }


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


    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_browser) {
    ... declare functions for that browser ...
    } else if (detect_some_other_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.
    , May 24, 2005
    #5
  6. On 24/05/2005 14:36, wrote:

    [snip]

    > if (detect_some_browser) {


    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.
    Michael Winter, May 24, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    515
  2. Bob
    Replies:
    24
    Views:
    1,537
  3. Sheila King

    Oddity with function default arguments

    Sheila King, Jun 12, 2004, in forum: Python
    Replies:
    2
    Views:
    271
    Heiko Wundram
    Jun 12, 2004
  4. Ian Collins

    Function pointer oddity

    Ian Collins, Aug 13, 2010, in forum: C++
    Replies:
    8
    Views:
    940
    James Kanze
    Aug 17, 2010
  5. [RaZoR]

    variable and function visibility problem

    [RaZoR], Sep 2, 2003, in forum: Javascript
    Replies:
    0
    Views:
    112
    [RaZoR]
    Sep 2, 2003
Loading...

Share This Page