用call來解釋this很形象,可是不是那麼嚴謹,詳情看補充1;javascript
比較嚴謹的解釋:一個函數能夠在多個環境中執行,函數執行時容許訪問環境中的其餘變量,this會指向調用函數的那個環境;html
比較易懂的解釋:java
call函數的第一個參數就是指定的外部環境,就是this
想要知道一個函數中的this是誰,大部分狀況下能夠去函數調用棧中找上一個函數看到。node
1.默認綁定瀏覽器
2.隱氏綁定app
3.顯示綁定函數
function bind(fn, obj) { return function() { return fn.apply( obj, arguments ); }; }
4.new綁定this
// 執行new Foo()時發生的操做 var obj = {}; // 建立空對象 obj.__proto__ = Foo.prototype; // 鏈接到foo的原型,繼承機制 Foo.call(obj); // 綁定成上下文,並執行foo return obj; // foo中若是沒有return的話,return obj這個對象回去
// 非嚴格模式 function foo() { console.log( this.a ); } var a = 2; foo.call( null ); // 2
var a=10; function test(){ a=5; alert(a); alert(this.a); var a; alert(this.a); alert(a); } 執行test()和new test() 結果是什麼 答案: alert的內容:test(): 5,10,10,5 new test():5,undefined,undefined,5
// 用一個簡單的例子開個頭 // obj.fn是一種隱性綁定,將fn中的this指向obj // 可是this又被context覆蓋了,這種this丟失能夠引伸出優先級的問題。 obj.fn.call(context)
箭頭函數的this繼承上層函數prototype
var obj = { say: function () { setTimeout(() => { console.log(this) //obj }, 0) } }
當即執行函數執行時,obj仍是undefinedcode
var obj = { say: function () { function _say() { console.log(this) //window or global } return _say.bind(obj) }() } obj.say()
var length = 10; function fn() { console.log(this.length); } var obj = { length: 5, method: function(fn) { fn(); arguments[0](); // arguments.0() } }; obj.method(fn, 1); // 10 2
var a=10; var foo={ a:20, bar:function(){ var a=30; return this.a; } } foo.bar() (foo.bar)() (foo.bar=foo.bar)() (foo.bar,foo.bar)() // 20 20 10 10
var num = 1; function codequn(){ 'use strict'; console.log('codequn: ',this.num++); } function codequn2(){ console.log('codequn2: ',++this.num); } (function(){ 'use strict'; codequn2(); })(); codequn(); // codequn2: 2 // Cannot read property 'num' of undefined
箭頭函數中的this是定義時所在對象的this,而不是執行時
const debounce = function(fn, time) { let timeout = null return function() { const _self = this clearTimeout(timeout) timeout = setTimeout(()=>{ console.log(this === _self) //true fn.call(this, ...arguments) }, time) } }
參考:
《你不知道的javascript上卷》;
https://www.zhihu.com/questio...;
http://www.ruanyifeng.com/blo...;
https://developer.mozilla.org...;