如果没有this,如何在sayName里找到代表“自己“这个对象?
let people = { name: 'hunger', sayName: function() { console.log(people.name) // 怎样找到自己的name属性 } }
可以用 this 代表“自己“这个对象
let people = { name: 'hunger', sayName: function() { console.log(this.name) } }
所以this出现的典型场景是: 在一个对象的方法里找当前对象(this)的其他属性或者方法。
换一种说法: this 代表当前this直属的函数所属的对象。
来看一个实际点的例子,以下代码里this分别都指什么?第9行代码对吗?
const app = { init() { this.$btn = document.querySelector('button') this.bind() }, bind() { this.$btn.onclick = function() { console.log(this) this.getData() //这样写对吗,如果不对该如何修改? } }, getData() { console.log('get data...') } } app.init()
你可能已经猜对里答案。
那我们如何修改呢?下面有几种写法:
const app = { init() { this.$btn = document.querySelector('button') this.bind() }, bind() { let self = this this.$btn.onclick = function() { console.log(this) // 这个this 还是 btn 对象 self.getData() //self 代表外面的this,也就是app } }, getData() { console.log('get data...') } } app.init()
在第7行,我们先把this(这里的this代表app对象)换个名字保存起来,在第9行此刻的this代表btn对象,如果想适用app对象可以使用self。
const app = { init() { this.$btn = document.querySelector('button') this.bind() }, bind() { this.$btn.onclick = () => { console.log(this) // 在确定this直属的函数时,不考虑箭头函数 this.getData() // 所以当前this直属的函数是bind } }, getData() { console.log('get data...') } } app.init()
当我们去找this的直属函数时,需要忽略箭头函数。第8行的this的直属函数是bind。
刚刚说过 this 默认指代当前this直属的函数所属的对象,为了让大家深刻理解“所属”这个词的含义,下面给一些反例。
var name = '饥人谷' var people = { name: '若愚', sayName() { console.log(this.name) } } var sayAgain = people.sayName function sayName(){ console.log(this.name) } people.sayName() sayAgain() sayName()
如果能给出正确的答案,那再看下面一个更隐晦的例子。
let arr = [] for(let i=0; i<3; i++){ arr[i] = function() { console.log(this) } } arr[0]() let fn = arr[0] fn()
let people = { name: '若愚', sayName() { setTimeout(function(){ console.log(this.name) }, 0) } } people.sayName()
箭头函数
let people = { name: '若愚', sayName() { setTimeout(() => { console.log(this.name) }, 0) } } people.sayName()
刚刚说过 this 默认指代当前this直属的函数所属的对象。假设我们想让this换个对象该怎么办?用call/apply/bind来修改它。
let obj = { fn(a, b) { console.log(this) } } obj.fn(1, 2) //等价于 obj.fn.call(obj, 1, 2) // 所以 this 是 obj obj.fn.apply(obj, [1, 2]) obj.fn.bind(obj)(1, 2)
call/apply/bind里面第一个参数传什么,函数里面的this就是什么。
let obj = {name: '饥人谷'} function sayName(){ console.log(this.name) } let fn = sayName.bind(obj) fn() // 输出: '饥人谷'
看一个复杂但更实际点但例子
let app = { container: document.querySelector('body'), init: function(){ //点击的时候会执行 sayHello,sayHello 里面的 this 代表 body 对象 this.container.addEventListener('click', this.sayHello) //点击的时候会执行 sayHello,sayHello 里面的 this 代表 app 对象 this.container.addEventListener('click', this.sayHello.bind(this)) }, sayHello: function(){ console.log(this) } } app.init()
有时候我们会在class或者构造函数里看到this:
function Wife(name) { this.name = name } Wife.prototype.showSkill = function() { console.log('我是' + this.name + ', 我的技能是唱歌、跳舞、打游戏') }
一个直男幻想着:如果我以后有个女神老婆,她的技能最好是唱歌、跳舞、打游戏。上面代码里的this(出现在构造函数内和原型的方法内)就代表幻想的那个未来的那个“她”。
let wife = new Wife('新桓结衣') wife.showSkill()
此刻真正的 wife 才创建,之前幻想时对 她(this) 的操作才真正开始实施。对this操作就是对wife的操作。 **
当看到this时,想知道它是什么,需要看
** 此为饥人谷前端系统班讲义,如需转载或者了解课程,联系微信 xiedaimala03。