this 本質是一個綁定, 在函數被調用時創建。它的指向是徹底由函數被調用的調用點來決定的。 function baz() { console.log(this);//由於baz函數的調用點在全局做用域,因此this指向全局變量 } baz();//這裏就是baz函數的調用點
在函數體內部指代函數當前的運行環境。從而實現乾淨的 API 設計和更容易的複用。
top-level scopegit
1) In browsers, the top-level scope is the global scope. This means that within the browser var something will define a new global variable.In Node.js this is different. The top-level scope is not the global scope; var something inside a Node.js module will be local to that module. 2) 可是在Node REPL下,與瀏覽器的行爲保持一致(timers除外) In browsers var that = this; setTimeout(function() { console.log(this);//window }, 0); Node REPL var that = this; setTimeout(function() { console.log(this);//Timeout {...} }, 0); setInterval 結果相同
嚴格模式下github
指定的this不在被封裝爲對象,並且若是沒有指定this,則this的值爲undefined sloppy mode function foo() { console.log(this); } foo.apply("test"); //==>String {"test"}0: "t"1: "e"2: "s"3: "t"length: 4...[[PrimitiveValue]]: "test" strict mode function foo() { "use strict"; console.log(this); } foo.apply("test"); //==>test
調用方法時沒有明確對象,this指向全局對象瀏覽器
sloppy mode In browsers,this指向window console.log(this);//window Node REPL, this指向global console.log(this);//global strict mode In browsers,this指向window "use strict"; console.log(this);//window Node REPL, this指向global "use strict"; console.log(this);//global
匿名函數執行時當前對象是全局對象app
sloppy mode In browsers, (function() { console.log(this);//window })(); Node REPL (function() { console.log(this);//global })(); strict mode In browsers, (function() { "use strict"; console.log(this);//undefined })(); Node REPL (function() { "use strict"; console.log(this);//undefined })();
強制一個函數調用使用某個特定對象做爲 this 綁定,而不在這個對象上放置一個函數引用屬性
就 this 綁定的角度講,call(..) 和 apply(..) 是徹底同樣的
callide
function foo() { console.log(this.a); } var obj = { a: 2 }; foo.call(obj); //==>2 強制函數foo()的 this 指向 obj
apply函數
function foo() { console.log(this.a); } var obj = { a: 2 }; foo.apply(obj); //==>2 強制函數foo()的 this 指向 obj bind 返回一個硬編碼的新函數,它使用你指定的 this 環境來調用本來的函數 function foo(something) { console.log(this.a, something); return this.a + something; } var obj = { a: 2 }; var a = 6; var bar = foo.bind(obj);//使用obj做爲this環境調用foo() var b = bar(3); // 2 3 console.log(b); // 5 var test = bar.bind(window);//2 3 console.log(test(3)); // 5
傳遞 null 或 undefined 做爲 call、apply 或 bind 的 this 綁定參數,那麼這些值會被忽略掉。ui
sloppy mode function foo() { console.log(this); } var obj = {}; foo.call(null);//window or global foo.apply(null);//window or global var bar = foo.bind(null); console.log(bar());//window or global strict mode "use strict"; function foo() { console.log(this); } var obj = {}; foo.call(null);//null foo.apply(null);//null var bar = foo.bind(null); console.log(bar());//null
newthis
將新構建的對象被設置爲函數調用的 this 綁定 function foo(a) { console.log(this); this.a = a; } var bar = new foo(2);//構建了一個新的對象(foo {a: 2})並把這個新對象做爲 foo(..) 調用的 this console.log(bar); //foo {a: 2} console.log(bar.a); // 2
arrow functions編碼
箭頭函數從封閉它的(函數或全局)做用域採用 this 綁定 function foo() { // 返回一個箭頭函數 return (a) => { //箭頭函數在詞法上捕獲 foo() 被調用時的 this(obj1) // 這裏的 `this` 是詞法上從 `foo()` 採用的 console.log(this.a); }; } var obj1 = { a: 2 }; var obj2 = { a: 3 }; var bar = foo.call(obj1); bar.call(obj2); //2
Refer:設計
https://github.com/CuiFi/You-Dont-Know-JS-CN https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this