如下若是沒說起,則爲嚴格模式。
js中做用域有兩種:python
詞法做用域指在書寫代碼時就被肯定的做用域。
看以下代碼babel
var value = 1; function foo() { console.log(value); } function bar() { var value = 2; foo(); } bar();// 結果是1
動態做用域指在代碼運行時才被肯定的做用域。
js中只有this的做用域是動態做用域app
初學js時,會想固然認爲this遵循某一條規律,就像物理學那樣,然而並非。
this的綁定分爲五種狀況,這五種狀況之間毫無規律可言。不過好在都很簡單。框架
當以以下形式執行一個函數時,this爲默認綁定;async
func()
與函數調用嵌套多少層如何嵌套無關函數
/* 全是undefined */ function printThis(){ return this } var obj = { say(){ console.log('obj.say',printThis()) } } function funcB(){ console.log('funcB',printThis()); obj.say(); } console.log('funcA',printThis()) obj.say() funcB()
當以以下行駛執行一個函數時,this爲隱式綁定;工具
a.b.func()
此時this指向點前面一個對象this
class T { dotInvoke() { console.log('dotInvoke', this.sayThis()) } sayThis() { return this } assignInvoke() { var sayThis = this.sayThis; console.log('assignInvoke', sayThis()) } } var tt = new T(); tt.dotInvoke()// 指向T tt.assignInvoke()// undefined
function printThis(){ return this } var obj = {}; obj.say = printThis; obj.say()/* 指向obj */
極爲常見的是回調函數的this是undefined,由於回調函數被複制給參數,參數再調用時變成了默認綁定翻譯
function asyncFun(cb){ cb() } var obj = { callback(){ console.log(this) } } obj.callback()/*隱式綁定 obj */ asyncFun(obj.callback);/*默認綁定 undefined */
箭頭函數會讓this指向最近的函數或全局做用域code
function foo() { // 返回一個箭頭函數 return (a)=>{ //this 繼承自 foo() return this.a } ; } var obj1 = { a: 'obj1' }; var obj2 = { a: 'obj2' } var arrow1 = foo.call(obj1); var arrow2 = foo.call(obj2); var arrow3 = foo(); console.log('arrow1',arrow1())/* obj1 */ console.log('arrow2',arrow2())/* obj2 */ console.log('arrow3',arrow3())/* undefined,嚴格模式下報錯 */
var printThis = ()=>this; console.log('printThis',printThis());/* global */
class Test { printThis = ()=>{ return this } } //會被babel翻譯成 var test = function test() { var _this = this; this.printThis = function () { return _this; }; };
call, apply, bind指定this指向
構造函數,ES6中的class
new構造函數,new class時,this指向實例