一日,見「use strict」,冥想許久……html
系列列表:
從use strict看JS(一):this與箭頭函數
從use strict看JS(二):函數傳參模式與argumentsjava
use strict指js的嚴格模式,還沒了解的看這裏:Javascript 嚴格模式詳解git
use strict有3點比較重要github
函數調用this爲undefined面試
arguments。不容許對arguments賦值。禁止使用arguments.callee。arguments再也不追蹤參數的變化babel
不用var聲明不會提高成全局變量,而是報錯閉包
use strict還有一些常人不易寫錯的,不歸入寫做範圍:app
對象不能有重名的屬性,函數不能有重名的參數函數
規定保留字。class, implements
迴歸正題,什麼是函數調用?爲什麼嚴格模式函數調用要將this指向undefined?
首先牢記:js function有四種方式調用,每一種的this都不一樣。
當函數被保存爲對象的屬性時,咱們稱這個函數爲方法。方法調用的this就綁定到該對象
var dog={ name:"doge", sayName:function(){ console.log(this.name); } } //輸出doge,this綁定到了dog dog.sayName();
聲明一個function而後調用。非嚴格模式this指向window,嚴格模式是undefined
function sayName(){ console.log(this); } function sayNameStrict(){ "use strict"; console.log(this); } //指向window sayName(); //開啓嚴格模式,指向undefined sayNameStrict();
這在對象、對象繼承用的比較多,經過new來使用,this指向new出來的新對象。
後面會有文章講解new如何實現,到時候就會很清楚。
function Dog(name){ this.name=name; } var dog=new Dog("doge"); //this指向dog console.log(dog.name);
這類就是改變this,apply和call是很重要的,因此許多面試都會問,以後的文章咱們會看到它們的強大做用。
那就是函數調用了。這是js的一個設計錯誤,this應該綁定到外部函數的this變量,
這個錯誤便是「函數調用」this綁定的錯誤。嚴格模式規定,this不指向window了,但並無解決這個問題,因而箭頭函數來了。
var dog={ name:"doge", sayName:function(){ return function(){ console.log(this); } } } // 此時是函數調用,this指向window dog.sayName()();
箭頭函數怎麼解決這個問題呢?其實用了閉包,改爲下面這樣,babel啥的也是這樣作的。
var dog = { name: "doge", sayName: function sayName() { var _this = this; return function () { console.log(_this); }; } };
那若是嵌套了多層箭頭函數?對閉包來講是同樣的
var dog={ name:"doge", sayName:function(){ return ()=>{ return ()=>{ console.log(this); } } } }
至關於
var dog = { name: "doge", sayName: function sayName() { var _this = this; return function () { return function () { console.log(_this); }; }; } };
那若是函數的屬性就是箭頭函數?沒有這樣用的!你會拿到window
var dog={ name:"doge", sayName:()=>{ console.log(this); } } // this指向window,由於箭頭函數 dog.sayName();
這是一本書,文末有連接。
the good parts說過:js語言有些地方設計得很差,因而後來的標準不斷地補坑。
the good parts又說過:js 函數調用this綁定到window是一個設計錯誤
等等,嚴格模式函數調用this爲什麼指向undefined??
首先,不應指向window,因此換一個。
其次,指向undefined有一個好處,構造函數通常不要直接運行,那要是強行運行呢?this指向window會給window添加許多屬性,有擾亂命名空間之嫌,指向undefined以後,你強行運行我就強行報錯!
function Dog(name){
this.name=name;
}
//會給window增長name屬性,改爲嚴格模式就會TypeError
Dog("doge");
固然,use strict不能解決全部問題,因此有了箭頭函數