前端进阶之如何正确判断this的指向?
生活随笔
收集整理的這篇文章主要介紹了
前端进阶之如何正确判断this的指向?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
- 作者:陳大魚頭
- github: KRISACHAN
- 鏈接:github.com/YvetteLau/S…
- 背景:最近高級前端工程師 劉小夕 在 github 上開了個每個工作日布一個前端相關題的 repo,懷著學習的心態我也參與其中,以下為我的回答,如果有不對的地方,非常歡迎各位指出。
例子
<script>// 瀏覽器正常情況下console.log(this === window) // true </script> <script>// 函數調用a = 10;function fn1 () {console.log(this.a)}fn1() // 10b = 2console.log(this.b) //2function fn2 () {this.b = 3}fn2()console.log(this.b) // 3 </script> <script>// 方法調用function test () {console.log(this.x)}x = 2var o = {}o.x = 1o.m = testo.m() // 1 </script> <script>// 構造函數調用x = 2function test () {this.x = 1}var o = new test()console.log(x) // 2 </script> <script>// apply調用x = 0function test () {console.log(this.x)}var o = {}o.x = 1o.m = testo.m.apply(o) // 1 </script> <script>// 函數 apply調用var zz = {};zz.a = 1000;a = 10;function fn1 () {console.log(this.a)}fn1.apply(zz) // 1000b = 2console.log(this.b) //2function fn2 () {this.b = 3}fn2.apply(zz)console.log(this.b) // 2 </script> <script>// 函數 apply調用var qqq = {a: 1}var ttt = {a: 2}var mmm = {a: 3}function fq () {console.log(this)}fq.bind(qqq).bind(ttt).bind(mmm)() // {a: 1} </script> <script>// forEachvar arr = [1, 2, 3, 4]var newarr = [5, 6, 7, 8]var newnewarr = [9, 10, 11, 12]arr.forEach(function (e, i, a) {console.log(this) // newarr}, newarr)arr.forEach((e, i, a) => {console.log(this) // window}, newarr) </script> <script>// 立即執行函數(function () {console.log(this) // window})()var o = {};o.x = 999;(function () {console.log(this) // {x:999}}).apply(o);(() => {console.log(this) // window})();(() => {console.log(this) // window}).apply(o) </script> <script>console.log(this === window) // true </script> <script>var k = {a: 1,b: 2,c: 3}const fn1 = function () {console.log(this)}fn1() // undefinedfn1.apply(k) // {a: 1, b: 2, c: 3}k.m = fn1k.m() // {a: 1, b: 2, c: 3, m: ?} </script> <script>const o = {a: 1,b: 2,c: 3}const fn2 = () => {console.log(this)}fn2() // windowfn2.apply(o) // windowo.m = fn2o.m() // window </script> <script>const oo = {d: function () {console.log(this)},e: () => {console.log(this)}}const ooo = {a: 1,b: 2,c: 3}oo.d() // {d: ?, e: ?}oo.e() // windowoo.d.apply(ooo) // {a: 1, b: 2, c: 3}oo.e.apply(ooo) // windowvar xxx = oo.dvar yyy = oo.exxx() // undefinedyyy() // window </script> <script>// forEachvar arr = [1, 2, 3, 4]var newarr = [5, 6, 7, 8]var newnewarr = [9, 10, 11, 12]arr.forEach(function (e, i, a) {console.log(this) // newarr}, newarr)arr.forEach((e, i, a) => {console.log(this) // window}, newarr) </script> 復制代碼總結
上面簡單列了 window 下的幾種情況,但其實在node下的情況也類似。 其實法則總結起來就是下面幾點:
在ECMA內, this 會調用 原生方法 ResolveThisBinding() 原生方法ResolveThisBinding使用正在運行的執行上下文的LexicalEnvironment確定關鍵字this的綁定。 ResolveThisBinding執行以下步驟:
原生方法GetThisEnvironment找到當前提供關鍵字 this 綁定的環境記錄。 GetThisEnvironment 執行以下步驟:
注意:步驟2中的循環必須終止,因為列表的環境總是以全局環境這個綁定。
如果你、喜歡探討技術,或者對本文有任何的意見或建議,你可以掃描下方二維碼,關注微信公眾號“魚頭的Web海洋”,隨時與魚頭互動。歡迎!衷心希望可以遇見你。
總結
以上是生活随笔為你收集整理的前端进阶之如何正确判断this的指向?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2018-2019-2 20165330
- 下一篇: 给自己看的flex布局方法