js this细节

this 是在运行时进行绑定的,它取决于函数调用时的执行上下文,并非指向自身也并非指向函数作用域。
 
this的绑定规则:
1.默认绑定
function foo() {
console.log( this.a );
}
var a = 2;
foo(); // 2
此处的foo()是直接使用不带任何修饰的函数引用进行调用的,此时的调用应用了this的默认绑定,也就是this指向全局对象。
 
注意:
如果是严格模式,那么全局对象无法默认绑定,此时this会绑定undefined。
function foo() {
"use strict";
console.log( this.a );
}
 
2.隐式绑定
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
obj.foo(); // 2
当函数引用有上下文对象时,隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象,此处即为obj。
 
注意:
1.对象属性引用链中只有最后一层会影响调用位置,形如obj1.obj2.foo(),this只跟obj2有关。
2.隐式丢失
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo; // 函数别名!
var a = "全局"; // a 是全局对象的属性
bar(); // "全局"
函数别名此处只是将函数赋予了新的变量,并没有调用,真正调用在最后一步,此时会采用默认绑定。
 
3.显示绑定
这个老生常谈了,就是使用函数的 call(..) 和apply(..) 方法
function foo() {
console.log( this.a );
}
var obj = {
a:2
};
foo.call( obj ); // 2
 
注意:
1.当你不传参数时,默认绑定全局对象
2.硬绑定bind,如果你把 null 或者 undefined 作为 this 的绑定对象传入 call、apply 或者 bind,这些值在调用时会被忽略,实际应用的是默认绑定全局对象
 
4.new绑定
function foo(a) {
this.a = a;
}
var bar = new foo(2);
console.log( bar.a ); // 2
使用 new 来调用 foo(..) 时,我们会构造一个新对象并把它绑定到 foo(..) 调用中的 this上
 
优先级:
new绑定>显示绑定>隐式绑定>默认绑定
 
5.箭头函数=>
当你使用箭头函数,它将打破以上规则,而是根据外层(函数或者全局)作用域来决定 this
function foo() {
// 返回一个箭头函数
return (a) => {
//this 继承自 foo()
console.log( this.a );
};
}
var obj1 = {
a:2
};
var obj2 = {
a:3
};
var bar = foo.call( obj1 );
bar.call( obj2 ); // 2, 不是 3 !
箭头函数会捕获调用时 foo() 的 this。由于 foo() 的 this 绑定到 obj1,
bar(引用箭头函数)的 this 也会绑定到 obj1,箭头函数的绑定无法被修改,new也不行。
 
 
 
 
posted @ 2020-08-04 16:41  你风致  阅读(114)  评论(0编辑  收藏  举报