前言

javascript中的this到底是个什么东西?表示学了这么久有时候还是会出现混淆,她简直像个恶魔!
群里大神一句话说过是指向直接调用她的对象,也就是点前的对象,我研究了下,终是有所领悟。

JavaScript中的this

她是个啥?

首先,this是javascript语言的关键字之一,指函数运行时的当前对象,那既然和函数运行有关,js中函数有哪些调用模式呢?

1.纯粹的函数调用
2.对象的方法调用
3.构造函数的调用
4.apply、call调用

来来来,让我来一步一步解开她的衣衫

老司机

1.纯粹的函数调用

函数调用 即function name()模式,这也是我们使用的最多的一种方式,其属于全局调用,浏览中的默认情况下函数内部的this指向window,当然是在非严格模式下。

this.name = 'remo';
function showName() {
console.log(this.name);
console.log(this === window);
}
showName()
//remo
//true

上面的例子相当于

widow.showName()

这也是为什么可以读取到全局定义的name属性的原因。

2.对象的方法调用

当一个函数作为对象的某个属性方法被调用的时候

var obj = {
name: 'remo',
showName: function() {
console.log(this.name);
}
};
obj.showName();
//remo

可以看出this指向的是obj这个对象,其实本质上讲函数调用形式内部this就是指向调用它的那个对象。

再来

var showName = function() {
console.log(this.name);
}
obj = {
name: 'remo',
showName: showName
};
obj.showName();
//remo

结果是不变的,在js中,一切都是对象,而这里也只是, 将objshowName属性指向,showName函数的引用地址。

继续

当我们把showName方法赋值给一个变量,又会有什么事情发生呢?

var obj = {
name: 'remo',
showName: function() {
console.log(this.name);
}
};
var tempShowName = obj.showName;
tempShowName()
//undefined

为什么不是期望的那样输出remo呢。objshowName方法是一个对象,当把它赋值给了tempShowName变量,此时便和obj没什么关系了,也就是和下面的等价了

window.tempShowName()

window上此事并没有name属性,输出自然是undefined

3.构造函数调用

当使用new去调用一个构造函数的时候,内部的this,指向的是实例化出来的对象。

var Person = function (name, sex) {
this.name = name;
this.sex = sex;
console.log(this);
};
var p1 = new Person('remo', 'boy');
// Person {name: 'remo', sex: 'boy'};

构造函数也是函数,所以当你用普通调用方式调用时

var Person = function (name, sex) {
this.name = name;
this.sex = sex;
console.log(this);
};
Person('remo', 'boy');
//这个时候相当于给window对象添加了name和sex两个属性。
window.name // 'remo'
window.sex // 'boy'

4.apply、call方法调用

使用callapply方式去调用一个函数的时候,内部的this指向的是传进来的第一个参数,当第一个参数是undefined或者null的时候,依旧指向window

var showName = function() {
console.log(this);
}
showName();//window
showName.call(undefined);//window
showName.call(null);//window
showName.call(remo);//remo

5.箭头函数

在ES6中的新规范中,加入了箭头函数,它比普通函数方便,清晰了许多,但关于this的指向,普通函数的this是运行时候决定的,而箭头函数则是定义的时候就决定的了,它内部本身是不包含this的。

var obj = {
name: 'remo',
showName: function() {
console.log(this.name);
},
showNameLater: function() {
setTimeout(()=>{
console.log(this.name);
},1000)
}
};
obj.showNameLater();
//remo
var obj = {
name:'remo',
showName: () => {
console.log(this.name);
}
};
obj.showName();
//undefined

最后

文章有疏漏与错误之处,望指出!

Comments

⬆︎TOP