开发者

Learning JavaScript variable scope and object instantiation

var foo = (function() {
    var proxy = {},
        warning = false;

    proxy.warn = function(msg) {
        if 开发者_运维知识库(!warning) {
            warning = true;
            alert(msg);
        }
        return this; //For the purpose of method chaining we return proxy object.
    }

    function func() {
        alert(warning); //This is a private function relative to foo.
    }

    return proxy;
}());

foo.warn(); //will alert
foo.warn(); //will not alert since warning has been set to true

I am confused about instantiation here since new keyword is not used who is holding the value of warning? Is there any leak here in terms of the scope warning lives in.

Thank you.


Well a live in the top closure function function() {....

foo is holding the proxy object you are returning, it means that everything who are not in this proxy object are private and cant be accessed from foo. If you want to get the value of a you can add a new function returning a =>

proxy.getValueOfA=function(){return a}

then you can call foo.getValueOfA()

As a remark:

var proxy={}

is the short form of var proxy=new Object() so there is an instanciation.


Both proxy.method and func have access to a via the closure property. For more information about scope and objects, check out this article that surfaced recently: A Concise, Executable Guide to JavaScript Objects, Variables, Functions, and Prototypes

The code that you've posted fits what's known as the "module pattern" and is becoming a very popular way to define objects in JavaScript as it makes private variables and methods easy to create (by taking advantage of the closure property as mentioned earlier).


This answer to another question really helped me expand my understanding of how javascript objects work:

JavaScript function aliasing doesn't seem to work

As for your code snippet, let's break it down. Start by looking at the high-level structure: var foo = ( exrpession );. You could just as easily say: var foo = expression;, but IIRC the parentheses are needed to handle an IE-specific quirk.

Now, in this case the expression is an anonymous function. Javascript is perfectly fine with you defining a function with no name. Just don't expect to call it unless you save a reference some where. You can also call an anonymous function immediately after the declaration, like this:

function() {
     alert('test');
     return 42;
}();

This should look suspiciously similar to the basic structure used for the expression from your code snippet. Hopefully you can easily see that the 42 from my sample could just as easily be an object.

So the question remains, why would you do this? Remember that in javascript, functions are also objects. As a good student of OOP, you probably like to make some members of your objects private. However, javascript doesn't have anything built-in to support this. Fortunately, it just happens that if you return an object from that inner function it will have access to other variables defined in that function, but outside code will not have any way to access them. So you have, in effect, created an object with private members.


this

    return proxy;
}());

should be this

    return proxy;
})();

and this

function() {
     alert('test');
     return 42;
}();

does not work ... syntax error. you should try your code before you put it on here. pretty sure you meant this:

(function() {
     alert('test');
     return 42;
})();

also, that fact that you're returning a private member kind of defeats the whole point of scope closure, but it'll work...

var foo = (function() {
    var proxy = {}, // private
    proxy.warn = function(msg) {
    ...
    return proxy; // publicly accessible

it's the same as

var foo = { warn: function(){ /* code */ } };
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜