javascript
Effective JavaScript Item 33 让构造函数不再依赖newkeyword
本系列作為EffectiveJavaScript的讀書筆記。
?
在將function當做構造函數使用時,須要確保該函數是通過newkeyword進行調用的。
function User(name, passwordHash) {this.name = name;this.passwordHash = passwordHash; }
假設在調用上述構造函數時。忘記了使用newkeyword。那么:
var u = User("baravelli", "d8b74df393528d51cd19980ae0aa028e"); u; // undefined this.name; // "baravelli" this.passwordHash; // "d8b74df393528d51cd19980ae0aa028e"
能夠發現得到的u是undefined。而this.name以及this.passwordHash則被賦了值。可是這里的this指向的則是全局對象。
?
假設將構造函數聲明為依賴于strict模式:
function User(name, passwordHash) {"use strict";this.name = name;this.passwordHash = passwordHash; } var u = User("baravelli", "d8b74df393528d51cd19980ae0aa028e"); // error: this is undefined
那么在忘記使用newkeyword的時候,在調用this.name= name的時候會拋出TypeError錯誤。這是由于在strict模式下。this的默認指向會被設置為undefined而不是全局對象。
?
那么,是否有種方法可以保證在調用一個函數時,不管使用了newkeyword與否,該函數都可以被當做構造函數呢?以下的代碼是一種實現方式。使用了instanceof操作:
function User(name, passwordHash) {if (!(this instanceof User)) {return new User(name, passwordHash);}this.name = name;this.passwordHash = passwordHash; }var x = User("baravelli", "d8b74df393528d51cd19980ae0aa028e"); var y = new User("baravelli", "d8b74df393528d51cd19980ae0aa028e"); x instanceof User; // true y instanceof User; // true
以上的if代碼塊就是用來處理沒有使用new進行調用的情況的。當沒有使用new時。this的指向并非一個User的實例。而在使用了newkeyword時,this的指向是一個User類型的實例。
?
還有一個更加適合在ES5環境中使用的實現方式例如以下:
function User(name, passwordHash) {var self = this instanceof User ?
this : Object.create(User.prototype); self.name = name; self.passwordHash = passwordHash; return self; }
Object.create方法是ES5提供的方法。它可以接受一個對象作為新創建對象的prototype。
那么在非ES5環境中,就須要首先實現一個Object.create方法:
if (typeof Object.create === "undefined") {Object.create = function(prototype) {function C() { }C.prototype = prototype;return new C();}; }
實際上,Object.create方法還有接受第二個參數的版本號,第二個參數表示的是在新創建對象上賦予的一系列屬性。
?
當上述的函數確實使用了new進行調用時。也可以正確地得到返回的新建對象。這得益于構造器覆蓋模式(Constructor Override Pattern)。該模式的含義是:使用了newkeyword的表達式的返回值可以被一個顯式的return覆蓋。
正如以上代碼中使用了returnself來顯式定義了返回值。
?
當然。以上的工作在某些情況下也不是必要的。可是,當一個函數是須要被當做構造函數進行調用時,必須對它進行說明,使用文檔是一種方式。將函數的命名使用首字母大寫的方式也是一種方式(基于JavaScript語言的一些約定俗成)。
?
總結:
總結
以上是生活随笔為你收集整理的Effective JavaScript Item 33 让构造函数不再依赖newkeyword的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 赞亲情的古诗词句子204个
- 下一篇: 橙光游戏《乱世浮华》攻略04-27