文章博客

技术团队文档示例


【js】this的指向问题

<h4>this的指向问题</h4> <p>对于箭头函数的this总结如下:</p> <ul> <li>箭头函数不绑定this,箭头函数中的this相当于普通变量。</li> <li>箭头函数的this寻值行为与普通变量相同,在作用域中逐级寻找。</li> <li>箭头函数的this无法通过bind,call,apply来直接修改(可以间接修改)。</li> <li>改变作用域中this的指向可以改变箭头函数的this。</li> </ul> <p>eg. function closure(){()=&gt;{//code }},在此例中,我们通过改变封包环境closure.bind(another)(),来改变箭头函数this的指向。</p> <pre><code>/** * 非严格模式 */ var name = 'window' var person1 = { name: 'person1', show1: function () { console.log(this.name) }, show2: () =&gt; console.log(this.name), show3: function () { return function () { console.log(this.name) } }, show4: function () { return () =&gt; console.log(this.name) } } var person2 = { name: 'person2' } //普通函数 - 指向调用他的对象 - call可以改变this指向 person1.show1() //person1 person1.show1.call(person2)//person2 //箭头函数 - 指向全局对象window - call不能改变this的指向 person1.show2() //window 箭头函数绑定,this指向外层作用域,即全局作用域 person1.show2.call(person2)//window 箭头函数绑定,this指向外层作用域,即全局作用域 //普通函数双层 - 内层函数指向全局 - person1.show3()()//window window,默认绑定,这是一个高阶函数,调用者是window // 类似于`var func = person1.show3()` 执行`func()` person1.show3().call(person2)//person2 显式绑定,this指向 person2 person1.show3.call(person2)()//window //箭头函数 - person1.show4()() //person1 箭头函数绑定,this指向外层作用域,即person1函数作用域 person1.show4().call(person2)//person1 call不能改变箭头函数的指向问题 person1.show4.call(person2)()//person2 call先改变外层函数的this指向 - 内层箭头函数时指向外层的 </code></pre> <p>最后一个person1.show4.call(person2)()有点复杂,我们来一层一层的剥开。</p> <p>1、首先是var func1 = person1.show4.call(person2),这是显式绑定,调用者是person2,show4函数指向的是person2。 2、然后是func1(),箭头函数绑定,this指向外层作用域,即person2函数作用域 首先要说明的是,箭头函数绑定中,this指向外层作用域,并不一定是第一层,也不一定是第二层。</p> <p>因为没有自身的this,所以只能根据作用域链往上层查找,直到找到一个绑定了this的函数作用域,并指向调用该普通函数的对象。</p> <pre><code>function Person (name) { this.name = name; this.show1 = function () { console.log(this.name) } this.show2 = () =&gt; console.log(this.name) this.show3 = function () { return function () { console.log(this.name) } } this.show4 = function () { return () =&gt; console.log(this.name) } } var personA = new Person('personA') var personB = new Person('personB') personA.show1() // personA,隐式绑定,调用者是 personA personA.show1.call(personB) // personB,显式绑定,调用者是 personB personA.show2() // personA,首先personA是new绑定,产生了新的构造函数作用域, // 然后是箭头函数绑定,this指向外层作用域,即personA函数作用域 personA.show2.call(personB) // personA,同上 personA.show3()() // window,默认绑定,调用者是window personA.show3().call(personB) // personB,显式绑定,调用者是personB personA.show3.call(personB)() // window,默认绑定,调用者是window personA.show4()() // personA,箭头函数绑定,this指向外层作用域,即personA函数作用域 personA.show4().call(personB) // personA,箭头函数绑定,call并没有改变外层作用域, // this指向外层作用域,即personA函数作用域 personA.show4.call(personB)() // personB,解析同题目1,最后是箭头函数绑定, // this指向外层作用域,即改变后的person2函数作用域 </code></pre>

页面列表

ITEM_HTML