JavaScript复习—this绑定
先了解一下this的四种绑定
首先需要明确的一点是,this并不是在函数被定义时绑定,而是在函数被调用时。
this
的绑定规则有以下五种:
- 默认绑定(严格/非严格模式)
- 显示绑定(call、apply方法)
- 隐式绑定
new
绑定
1. 默认绑定
独立函数调用:直接调用函数,使用默认绑定;
严格模式:this绑定到
undifined
;非严格模式:函数在非严格模式时将默认绑定到全局对象上。
function foo() { console.log(this.a); } let a = 1; foo() // 1
2.隐式绑定
函数在被调用时,如果存在上下文对象,那么this会绑定到这个上下文对象上。
function foo() {
console.log(this.a)
}
let obj = {
a: 1,
foo: foo
};
let a = 2;
obj.foo(); // 1
显然这个函数foo()
被调用时落脚点是obj对象。obj对象里的foo引用了foo函数,所以当调用obj.foo()
时,隐式绑定了。
let foo = function () {
console.log(this.a)
}
let obj2 = {
a: 2
foo: foo
}
let obj1 = {
a: 1
obj2: obj2
};
obj1.obj2.foo(); // 2
(这个我没想好要怎么讲…先留着…)
但是应用隐式绑定this存在一个问题,那就是隐式丢失。
看下面这个栗子:
function foo() {
console.log(this.a)
}
let obj = {
a: 1,
foo: foo
};
let a = 2;
let bar = obj.foo;
bar(); // 2
bar是指向obj.foo的一个引用,可是实际上,它引用的是foo函数本身,所以在调用bar()
时,已经是作为独立函数调用了,这个时候执行的是默认绑定。
3. 显示绑定
通过call()、apply()的方法绑定。接受一个参数,为绑定的对象,在函数调用时,将this绑定到这个对象上。
function foo() {
console.log(this.a);
}
let obj = {
a: 1,
};
let a = 2;
foo.call(obj) // 1
在看刚才那个隐式丢失的栗子:
function foo() {
console.log(this.a)
}
let obj = {
a: 1,
foo: foo
};
let a = 2;
let bar = obj.foo;
bar.call(obj); // 1
所以用call()、apply()可以解决隐式丢失的问题。
4. new绑定
构造函数其实是使用new
操作调用的一个普通函数,包括内置函数在内的所有函数都可以用new
操作符来调用,称为构造函数调用。
实际上并不存在所谓的构造函数,确切的说是函数的构造调用。
new
一个函数会执行下面操作:
- 创建一个新的对象;
- 将这个新对象的__proto__指向构造函数的原型(prototype);
- 使用这个新对象调用函数,将函数的this绑定到这个新对象上;
- 如果函数里没有返回对象,那么返回这个创建的新对象。但是如果return 了一个对象,那么这个新对象作废。
function Foo(a) {
this.a = a;
}
let bar = new Foo(2);
console.log(bar.a); // 2
箭头函数和普通函数的this区别
- 普通函数: this指向调用这个方法的对象(谁调用我,我的this就绑定谁);
- 箭头函数: 其实箭头函数没有自己作用域下的this,箭头函数里的this对象,就是定义时所在的对象,而不是调用时所在的对象。
我之前的理解:其实箭头函数没有自己作用域下的this,它的this其实是定义时所在作用域的this值。换个说法,箭头函数的this其实是包裹这个箭头函数的普通函数的this值
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,可以邮件至 610193653@qq.com,谢谢啦!
文章标题:JavaScript复习—this绑定
本文作者:zzzwyyy
发布时间:2019-12-19, 15:56:59
最后更新:2019-12-19, 17:26:36
原始链接:http://yoursite.com/2019/12/19/JavaScript复习—this绑定/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。