本篇文章是you don't know js的this&object prototypes的第一章的读书笔记,链接地址如下:this or that
在本章节中,主要介绍了两个常混淆的点:
1、以为this代表function本身。
function foo(num) {
console.log( "foo: " + num );
// keep track of how many times `foo` is called
this.count++;
}
foo.count = 0;
var i;
for (i=0; i<10; i++) {
if (i > 5) {
foo( i );
}
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9
// how many times was `foo` called?
console.log( foo.count ); // 0 -- WTF?
虽然console.log("foo:"+num)输出了四次,但是最后的foo.count却还是0.
foo是一个函数,函数也是一个对象,所以foo.count是给foo这个对象加上一个count的属性。但是在foo函数中,又使用了this.count,通常这里就会一个令人困惑的事,以为this是指向foo的,也就是说this.count==foo.count。
但在测试中,却发现是输出0。明显的,this不是指向foo。
在foo函数中的,this.count,this是指向winodw这个对象的,而不是foo这个对象。
这里涉及到call-site问题。
call-site,就是函数被调用的位置。
function baz() {
// call-stack is: `baz`
// so, our call-site is in the global scope
console.log( "baz" );
bar(); // <-- call-site for `bar`
}
function bar() {
// call-stack is: `baz` -> `bar`
// so, our call-site is in `baz`
console.log( "bar" );
foo(); // <-- call-site for `foo`
}
function foo() {
// call-stack is: `baz` -> `bar` -> `foo`
// so, our call-site is in `bar`
console.log( "foo" );
}
baz(); // <-- call-site for `baz`
1、默认情况下,this会被绑定为call-site处的this。
2、如果一个函数是在一个对象内,那么this就是指向这个对象。
3、如果一个函数是在一个对象内,那么this就是指向这个对象。但是如果把这个函数复制给另外一个变量,再调用,那么this还是会被绑定到被调用处。
4、使用call和apply能够显示地绑定this。
5、使用new的话,会重新指明this。
这几种情况能够单处出现,也能够合在一起出现。但出现时,必然会出现一个优先级的问题。
优先级是:
new大于任何,然后call和apply其后,接着是在对象内,然后才是默认情况。