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 */ } };
精彩评论