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
nick
if there isn't one with a non-falsey value already - Create an anonymous function that…
- Creates a variable called
helloA
in its own scope - Outputs data using
console.log
containing "1" (as is),this
(thewindow
because 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 theinit
function in the context ofname
. - This defines
helloB
- Then it
console.logs
with "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
this
is defined on a per-function basis when the function call is made. When you call a function aso.f()
,this
will beo
within the function, and when you call it asf()
,this
will 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
init
property) to thename
property of the object. - It gets the value from the
init
property, which is a method delegate, and calls the method.
The anonymous function does this:
- It declares a local variable named
helloA
and 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 thehelloA
property (which doesn't exist). - It creates an anonymous function and assignes to the local variable
init
. - It creates an object with the property
init
and the value from the local variableinit
.
The anonymous function assigned to the init
property does this:
- It declares a local variable named
helloB
and 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 thename
property, not thenick
variable), and thehelloB
property (which doesn't exist).
精彩评论