示例1:
var name = "windowsName";
var a = {
name: "Cherry",
fn: function () {
console.log(this.name); // Cherry
}
}
a.fn(); // 等于 window.a.fn();
在这个例子中,函数 fn
是对象 a
调用的。
示例2:
var name = "windowsName";
var a = {
name : "Cherry",
func1: function () {
console.log(this.name)
},
func2: function () {
setTimeout(function () {
this.func1()
},100);
}
};
a.func2() // this.func1 is not a function
在这个例子中,func1
其实是setTimeout
调用的,而setTimeout
是属于Window
对象下的属性,所以func1
中的this
最后是指向Window
的。
示例3:
var name = "windowsName";
var a = {
name : "Cherry",
func1: function () {
console.log(this.name)
},
func2: function () {
setTimeout(() => {
this.func1()
},100);
}
};
a.func2() // Cherry
众所周知,ES6 的箭头函数是可以避免 ES5 中使用 this
的坑的。箭头函数的 this
始终指向函数定义时的 this
,而非执行时。箭头函数需要记着这句话:“箭头函数中没有 this
绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this
绑定的是最近一层非箭头函数的 this
,否则,this
为 Window
”。因为没有this
,因此箭头函数不能用作构造函数。
以下这个示例很好的说明了上面的结论:
const utils = {
add (a, b) {
return a + b;
},
plus: (a, b) => {
console.log(this);
return this.add(a, b) * b;
}
};
console.log(utils.plus(3, 5));
// 输出结果
// Window
// Uncaught TypeError: this.add is not a function
项目示例1:
项目中会用到许多监听事件,以及取消监听事件的需求,而监听事件需要传一个具名函数,以便取消监听,便有如下代码:
Component({
lifetimes: {
attached() {
wx.onKeyboardHeightChange(this.listener)
},
detached() {
wx.offKeyboardHeightChange(this.listener)
}
},
methods: {
listener(res) {
this.setData({
textHeight: res.height
})
}
}
上面这种写法会报错,错误如下:
TypeError: this.setData is not a function
发生上面错误的原因很简单,就是非箭头函数中this
永远指向最后调用它的那个对象。而最后调用setData
的那个对象肯定在wx.onKeyboardHeightChange
里面,所以找不到setData
函数,才会报上面错误,那我们再用箭头函数改良下:
Component({
lifetimes: {
attached() {
this.listener = (res) => {
this.setData({
textHeight: res.height
})
}
wx.onKeyboardHeightChange(this.listener)
},
detached() {
wx.offKeyboardHeightChange(this.listener)
}
}
上面代码就正常了,因为箭头函数的 this
始终指向函数定义时的 this
,而此时的this
就是指向attached
这个作用域了。