寫該系列文章的初衷是「讓每位前端工程師掌握高頻知識點,爲工做助力」。這是前端百題斬的第14斬,但願朋友們關注公衆號「執鳶者」,用知識武裝本身的頭腦。
this是javascript中的一個關鍵字,其使用方法相似於一個變量,是執行上下文中一個重要組成部分。其做用是能夠在函數體內部獲取當前的運行環境。
每一個函數的this是在調用的時候基於函數的執行環境綁定的,this的指向徹底取決於函數的調用位置。(下面均是在瀏覽器環境下進行測試的結果)
console.log(this); // window
(1)非嚴格模式下,this 默認指向全局對象windowjavascript
(2)嚴格模式下, this爲undefinedhtml
function fun() { console.log(this); // window }
對象內部方法的this指向調用這些方法的對象前端
(1)函數的定義位置不影響其this指向,this指向只和調用函數的對象有關;java
(2)多層嵌套的對象,內部方法的this指向離被調用函數最近的對象(window也是對象,其內部對象調用方法的this指向內部對象, 而非window)。數組
const obj = { a: 10, b: 20, add: function () { return this.a + this.b; } }; console.log(obj.add()); // 30 const add = obj.add; console.log(add()); // NaN
const obj = { a: 10, b: 20 }; const prototypeObj = { add: function () { return this.a + this.b; } }; Object.setPrototypeOf(obj, prototypeObj); console.log(obj.add()); // 30
function Fun() { this.a = 10; } const fun = new Fun(); console.log(fun.a); // 10
<button id="testId">按鈕</button> const btn = document.getElementById('testId'); btn.addEventListener('click', function() { console.log(this); // <button id="testId">按鈕</button> });
內聯事件中的this指向分兩種狀況:瀏覽器
(1)當代碼被內聯處理函數調用時,它的this指向監聽器所在的DOM元素前端工程師
<button onclick="console.log(this)">按鈕</button> // 輸出該DOM節點
(2)當代碼被包括在函數內部執行時,其this指向等同於 函數直接調用的狀況,即在非嚴格模式指向全局對象window, 在嚴格模式指向undefinedapp
<button onclick="clickFun()">按鈕</button> function clickFun() { console.log(this); // window }
function Fun() { this.a = 10; this.method = function() { setTimeout(function() { console.log(this); // window }, 1000); } } const fun = new Fun(); fun.method();
function Fun() { this.a = 10; this.method = function() { setTimeout(() => { console.log(this); // Fun {a: 10, method: ƒ} }, 1000); } } const fun = new Fun(); fun.method();
除了隱式綁定this的方式,還可以經過顯示綁定的方式,經過call、apply、bind方式改變this指向,對於這三者的區別後續將有專門的百題斬去闡述,本節主要進行一波簡單使用。
call()
方法使用一個指定的this
值和單獨給出的一個或多個參數來調用一個函數。
function method(val1, val2) { return this.a + this.b + val1 + val2; } const obj = { a: 1, b: 2 }; console.log(method.call(obj, 3, 4)); // 10
apply()
方法調用一個具備給定this
值的函數,以及以一個數組(或類數組對象)的形式提供的參數。
function method(val1, val2) { return this.a + this.b + val1 + val2; } const obj = { a: 1, b: 2 }; console.log(method.apply(obj, [3, 4])); // 10
bind()
方法建立一個新的函數,在bind()
被調用時,這個新函數的this
被指定爲bind()
的第一個參數,而其他參數將做爲新函數的參數,供調用時使用。
function method(val1, val2) { return this.a + this.b + val1 + val2; } const obj = { a: 1, b: 2 }; const bindMethod = method.bind(obj, 3, 4); console.log(bindMethod); // [Function: bound method] console.log(bindMethod()); // 10
擴展
call()
和 apply()
的區別是call()
方法接受的是參數列表,而apply()
方法接受的是一個參數數組;1.若是以爲這篇文章還不錯,來個分享、點贊吧,讓更多的人也看到函數
2.關注公衆號執鳶者,與號主一塊兒斬殺前端百題。測試