Still confused about JavaScript's 'this'
I've been reading through quite a few articles on the 'this' keyword when using JavaScript objects and I'm still somewhat confused. I'm quite happy writing object orientated Jav开发者_JAVA百科ascript and I get around the 'this' issue by referring the full object path but I don't like the fact I still find 'this' confusing.
I found a good answer here which helped me but I'm still not 100% sure. So, onto the example. The following script is linked from test.html with <script src="js/test.js"></script>
if (!nick) {
var nick = {};
}
nick.name= function(){
var helloA = 'Hello A';
console.log('1.',this, this.helloA);
var init = function(){
var helloB = 'Hello B';
console.log('2.',this, this.helloB);
}
return {
init: init
}
}();
nick.name.init();
What kind of expected to see was
1. Object {} nick.name, 'Hello A'
2. Object {} init, 'Hello B'
But what I get is this?
1. Window test.html, undefined
2. Object {} init, undefined
I think I understand some of what's happening there but I would mind if someone out there explains it to me.
Also, I'm not entirely sure why the first 'console.log' is being called at all? If I remove the call to the init function //nick.name.init() firebug still outputs 1. Window test.html, undefined. Why is that? Why does nick.name() get called by the window object when the html page loads?
Many thanks
Also, I'm not entirely sure why the first 'console.log' is being called at all?
nick.name = function(){
// ...
}();
Here you define a function, call it immediately (hence ()) and assign its return value ({init: init}) to nick.name
So the execution is:
- Create a variable called
nickif there isn't one with a non-falsey value already - Create an anonymous function that…
- Creates a variable called
helloAin its own scope - Outputs data using
console.logcontaining "1" (as is),this(thewindowbecause the function is executing in the global context instead of as a method), andthis.helloA(window.helloA, which doesn't exist. - Defines a function called
init - Returns an object which gets assigned to
nick.name - Then you call
nick.name.init()which executes theinitfunction in the context ofname. - This defines
helloB - Then it
console.logswith "2" (as is),this(name), andthis.helloB(nick.name.helloB- which doesn't exist)
So the first output you get is from console.log('1.',this, this.helloA);
I think your main problem is that you are confusing this.foo (properties on the object on which a method is being called) with variable scope (variables available to a function)
It's much simpler if you think about this as a function, not as a variable. Essentially, this is a function which returns current "execution context", that is, the object the current function was "applied" to. For example, consider the following
function t() { console.log(this)}
this will return very different results depending upon how you call it
t() // print window
bar = { func: t }
bar.func() // print bar
foo = { x: 123 }
t.apply(foo) // print foo
thisis defined on a per-function basis when the function call is made. When you call a function aso.f(),thiswill beowithin the function, and when you call it asf(),thiswill be the global object (for browsers, this is the window). You wrotenick.name = function(){...}();and the right-hand part is of the formf(), hence theWindow.var foo = bar;defines a local variable. It may not be accessed asthis.foo(well, except when you're at global scope, but that's silly). To define a member, you usually writethis.foo = bar;instead.
This is what your code does:
- It creates an object and assigns to the variable
nick. - It creates an anonymous function.
- It calls the function (in the window scope).
- It assigns the return value (an object containing the
initproperty) to thenameproperty of the object. - It gets the value from the
initproperty, which is a method delegate, and calls the method.
The anonymous function does this:
- It declares a local variable named
helloAand assigns a string to it. (Creating a local variable doesn't add it as a property to the current object.) - It logs
this(window) and thehelloAproperty (which doesn't exist). - It creates an anonymous function and assignes to the local variable
init. - It creates an object with the property
initand the value from the local variableinit.
The anonymous function assigned to the init property does this:
- It declares a local variable named
helloBand assigns a string to it. (Creating a local variable doesn't add it as a property to the current object.) - It logs
this(the object from thenameproperty, not thenickvariable), and thehelloBproperty (which doesn't exist).
加载中,请稍侯......
精彩评论