JavaScript中的this依赖于函数的调用方式,因此把this称为调用上下文很合适。
先来一个最简单的例子
1 2 3 4 5 6 7 8 9 10 11
| function ask(){ console.log(this.name) } var li_lei = { name: "han mei mei", ask: ask }
`这两个方法分别输出什么` li_lei.ask() => "li lei" han_mei_mei.ask() => "han mei mei"
|
稍微复杂一点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var li_lei = { name: "li lei", ask: function (){ console.log(this.name) } }
var han_mei_mei = { name: "han_mei_mei", ask: li_lei.ask }
`这两个方法分别输出什么` li_lei.ask() => "li lei" han_mei_mei.ask() => "han mei mei"
|
根据上面的两个例子引出一个概念,请记住:
function中的this一般情况下表示的是调用对象(调用对象.方法名())
那么接下来需要考虑一个问题,在js里经常把function作为回调函数传来传去,用什么手段可以让function中的this保持不变?
让function中的this“保持不变”
使用bind方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var li_lei = { name: "li lei", _ask: function(){ console.log(this.name) } } li_lei.ask = li_lei._ask.bind(li_lei)
var han_mei_mei = { name: "han mei mei" } han_mei_mei.ask = li_lei.ask
`这两个方法分别输出什么` li_lei.ask() => "li lei" han_mei_mei.ask() => "li lei"
|
改成用类来举例(类的声明用es6语法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class LiLei { constructor() { this.name = "li lei"; this.ask = this._ask.bind(this); } _ask(){ console.log(this.name); } }
var li_lei = new LiLei();
class HanMeiMei { constructor(li_lei_instance){ this.name = "han mei mei"; this.ask = li_lei_instance.ask } }
var han_mei_mei = new HanMeiMei(li_lei)
`这两个方法分别输出什么` li_lei.ask() => "li lei" han_mei_mei.ask() => "li lei
|
不使用bind实现同样的效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class LiLei { constructor() { this.name = "li lei"; var that = this; this.ask = function(){ console.log(that.name); } } }
var li_lei = new LiLei();
class HanMeiMei { constructor(li_lei_instance){ this.name = "han mei mei"; this.ask = li_lei_instance.ask } }
var han_mei_mei = new HanMeiMei(li_lei)
`这两个方法分别输出什么` li_lei.ask() => "li lei" han_mei_mei.ask() => "li lei
|
变复杂一点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class LiLei { constructor() { this.name = "li lei"; this.ask = this.bind_ask(); } bind_ask(){ var that = this; var fun = function(){ console.log(that.name); } return fun; } }
var li_lei = new LiLei();
class HanMeiMei { constructor(li_lei_instance){ this.name = "han mei mei"; this.ask = li_lei_instance.ask } }
var han_mei_mei = new HanMeiMei(li_lei)
`这两个方法分别输出什么` li_lei.ask() => "li lei" han_mei_mei.ask() => "li lei
|
使用ES6中的箭头函数来实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class LiLei { constructor() { this.name = "li lei"; this.ask = () => { console.log(this.name) }; } }
var li_lei = new LiLei();
class HanMeiMei { constructor(li_lei_instance){ this.name = "han mei mei"; this.ask = li_lei_instance.ask } }
var han_mei_mei = new HanMeiMei(li_lei)
`这两个方法分别输出什么` li_lei.ask() => "li lei" han_mei_mei.ask() => "li lei
|
ES6中的箭头函数和普通的function在处理this上是有差别的,根据上面的例子你应该已经明白了:
ES6的箭头函数中的this,永远保持不变,一只表示声明时的this