对于javascript中的this指向,做一点个人理解的简单记录。
我认为,this的指向分为两大类,‘静态’和 ‘动态’,‘静态’的指函数定义的时候就知道它的this指向;‘动态’指函数执行的时候才能知道this指向;
‘动态’
独立调用时this的指向
如果函数是独立调用的,也就是说,在非严格模式下,this指向Window
function aba() {
console.log(this)
}
aba(); // 打印出Window
再看一个例子
let obj = {
name: 'yan',
say(){
console.log(this)
}
}
let objSay = obj.say;
objSay(); //打印出Window
obj.say(); //{name: "yan", say: ƒ}
上面这个例子中,在对象中定义了say方法,将其用一个别的函数接收独立执行的时候,this是指向Window而不是obj。
隐式绑定
隐式绑定,也就是说谁调用这个函数,this指向谁,上面例子中的,obj调用了其say方法,打印出的this为obj本身,再来一个例子。
function foo() {
console.log(this);
}
let obj = {
a: 1,
foo: foo
}
obj.foo(); //{a: 1, foo: ƒ}
//可以看到,obj调用foo方法,this指向obj
显式调用
用call、apply、bind方法给函数显式指定this指向,这个时候的this指向均指向显式绑定的值,在这里不做赘述,简单来一个例子。
var person = {
fullName: function() {
return this.firstName
}
}
var person1 = {
firstName:"yan"
}
var person2 = {
firstName:"shao"
}
person.fullName.call(person1); // 将返回yan
new 绑定
new 是用来构造函数中实例化一个对象的,这个时候的this指向为构造出来的实例对象;
function Person(name, age) {
this.name = name;
this.age = age;
say() {
console.log(this.name, this.age);
}
}
let p1 = new Person('yan', 19);
p1.say(); // 输出 'yan' , 19
‘静态’
‘静态’的意思是,this指向并不是由函数执行的时候决定的,在函数定义的时候就就决定了this的指向;上节提到到四种绑定规则,直接调用、隐式绑定、显示绑定都无效,而箭头函数是无法当做构造函数的,这个可以自己验证下。
箭头函数中,是不存在this的,其this指向,取决于父环境中的this。
let obj = {
name: 2,
say: ()=>{
console.log(this);
}
}
obj.say(); //this指向window
上面的例子再, obj调用了say方法,如果根据上节的隐式绑定规则:谁调用指向谁, this应该指向obj,但是由于say方法是箭头函数,这种规则失效,this由obj的父环境决定,也就是window。
总结
对this指向做一个简单总结
| 大类 | 小类 | 说明 |
|---|---|---|
| 动态 | 默认绑定规则 | 默认指向window |
| 隐式绑定 | 谁调用指向谁 | |
| 显式绑定 | call、apply、bind显式指定this指向 | |
| new绑定 | 指向构造函数实例本身 | |
| 静态 | 箭头函数 | 箭头函数中本身没有this,由其父环境的this指向决定 |