关于this,我们想到的就是普通函数和箭头函数的this指向问题,那么我将一一举例说明
普通函数this
普通函数的this指向调用它的对象
function myFun(){
var name = '日月当空曌'
console.log(this.name) // undefined
console.log(this) // Window 对象
}
myFun() // 等价于 window.myFun()
myFun是在最外层作用域调用的,想当于 window.myFun() ,this指向调用它的对象window,所以打印是undefined
var o = {
name:'日月当空曌',
sayName:function(){
console.log(this.name)
}
}
o.sayName() //'日月当空曌'
let sayName1 = o.sayName
sayName1() // undefined
- 这里o.sayName() 调用函数的对象是o,this指向o,this.name 就是o.name
- 把o.sayName() 复制给一个新的变量,这时候调用,this指向window
构造函数this
构造函数this指向
function Person(){
this.name = '日月当空曌'
this.age = 18
}
let person = new Person()
console.log()
使用new调用函数,this指向新的对象
至于new创建对象经历了哪里步骤,请看js对象-构造函数
箭头函数this
箭头函数的this和普通函数不同,箭头函数的this对象就是定义时所在的this对象,而不是使用时所在的对象
学习箭头函数this之前需要明白一个问题,就是setTimeout和setInterval里回调函数this指向问题。
引用mdn的解释:**由setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字在非严格模式会指向 window (或全局)对象,严格模式下为 undefined,这和所期望的this的值是不一样的。**(https://developer.mozilla.org/zh-CN/docs/Web/API/Window/setTimeout)
箭头函数的this指向是固定不变的
function woo() {
setTimeout(function() {
console.log(this)
console.log('id:', this.id);
}, 100);
}
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
var id = 21;
woo.call({id:42}); //21
foo.call({ id: 42 }); // 42
我们已经知道setTimeout的参数如果是普通函数,this指向window(原因见上文),woo.call({id:42})会返回21,而箭头函数的this总是指向函数定义生效时所在的对象,意思就是this指向箭头函数父作用域的this,即foo的this,{id:42}
再看一个例子
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭头函数
setInterval(() => this.s1++, 1000);
// 普通函数
setInterval(function () {
this.s2++;
}, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100); // 3
setTimeout(() => console.log('s2: ', timer.s2), 3100);// 0
new Timer() Timer函数的this指向新的对象, 箭头函数的this指向父作用域的this,即新对象的this,也就是timer,而普通函数this指向window,所以 timer.s2的值不会改变
由此,可以看到箭头函数的this固定,这种特性很有利于封装回调函数
注意点
- 箭头函数不可以当做构造函数,不能使用new
- 没有argument对象
练习题
var Test ={
foo:"test",
func:function () {
var self=this;
console.log(this.foo);
console.log(self.foo);
(function () {
console.log(this.foo);
console.log(self.foo);
})();
}
};
Test.func();
运行结果是 test test undefined test
大家可能好奇的是undefined
其中
(function () {
console.log(this.foo);
console.log(self.foo);
})();
这是一个立即执行函数,他是自己去调用自己,this指向的是全局作用域
参考
www.cnblogs.com/pssp/p/5216… es6.ruanyifeng.com/#docs/funct…