當(dāng)前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
JS 对象机制深剖——new 运算符
生活随笔
收集整理的這篇文章主要介紹了
JS 对象机制深剖——new 运算符
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
- 其實(shí)關(guān)于?new?的討論,早有眾多前輩做了先行。然而作為 JS 對象機(jī)制系列的一個(gè)重要成員,這一篇不可少,而且按照自己的慣例,我將首先引用語言規(guī)范的內(nèi)容。另外,本篇引用到的規(guī)范內(nèi)容比較多,不過我會做詳細(xì)的說明,讀者朋友可自行選擇閱讀規(guī)范內(nèi)容。
考察 ECMAScript 語言規(guī)范中?new?運(yùn)算符的定義:
The new Operator
The production?NewExpression : new NewExpression?is evaluated as follows:- 注意到,這段定義中的 new 后的表達(dá)式不帶參數(shù),即是說,這段內(nèi)容針對的是諸如 obj = new Object; 這樣的用法——帶參數(shù)的用法如 str = new String(“test”); 將在下面給出。兩者有區(qū)別且區(qū)別不大。
回到上述定義,其大意是,new 后必須跟一個(gè)對象并且此對象必須有一個(gè)名為 [[Construct]] 的內(nèi)部方法(其實(shí)這種對象就是構(gòu)造器),否則會拋出異常,比如:
var Str = "test"; var aStr = new Str; // FF 顯示“Str is not a constructor” // IE 顯示“對象不支持此操作”var Num = new Number(999); var aNum = new Num; // 結(jié)果同上如果符合以上條件,那么引擎將調(diào)用其 [[Construct]] 內(nèi)部方法,并不提供入口參數(shù)。接下來便要考察此內(nèi)部方法。
另外,下面一段是 new 運(yùn)算符的帶參用法,由于和無參用法區(qū)別不大,讀者朋友可直接略過。
The production MemberExpression : new MemberExpression Arguments is evaluated as follows:考察 [[Construct]] 內(nèi)部方法,先給出語言規(guī)范的描述:
When the [[Construct]] property for a Function object F is called, the following steps are taken:- 引擎將先創(chuàng)建一個(gè)語言原生對象,即“{}”或“new Object”,在此我們稱之為 O,然后設(shè)置其內(nèi)部屬性標(biāo)識 [[Class]] 為“Object”。接下來,得到構(gòu)造器 F 的 prototype(根據(jù)后文的意思,它可能不是一個(gè)對象)。如果 F.prototype 是對象,那么將 O 的內(nèi)部 [[Prototype]] 屬性指向 F.prototype。
- 請注意,諸如 [[Prototype]] 等為引擎內(nèi)部標(biāo)識符,對我們并不可見。[[Prototype]] 正是用于給內(nèi)部維護(hù)原型鏈,雖然在我們看來,一個(gè)對象實(shí)例無法直接回溯到其原型(然而引擎內(nèi)部可以),必須通過構(gòu)造器中轉(zhuǎn),即 obj.constructor.prototype。
- 接著,如果 F.prototype 不是 object,那么將 O 的內(nèi)部 [[Prototype]] 屬性指向“the Object prototype object”(你可以參考這里)。等到 O 的 [[Prototype]] 有了自己的歸屬以后,引擎調(diào)用構(gòu)造器 F 的 [[Call]] 內(nèi)部方法,以 O 作為 this 對象,并將傳入 [[Construct]] 的參數(shù)作為入口參數(shù)——如果有的話(即諸如“new Object()”最后括號內(nèi)的參數(shù))傳遞過去。最后,如果 [[Call]] 的返回值是對象,那么創(chuàng)建成功并返回此對象,否則回頭重來。
根據(jù)這些內(nèi)容,我們完全可以構(gòu)造一個(gè)偽 [[Construct]] 方法來模擬此流程(其實(shí)已有眾多前輩做過此工作):
function MyObject(age) {this.age = age; }MyObject.construct = function() {var o = {}, Constructor = MyObject;o.__proto__ = Constructor.prototype;// FF 支持用戶引用內(nèi)部屬性 [[Prototype]] Constructor.apply(o, arguments);return o; };var obj1 = new MyObject(10); var obj2 = MyObject.construct(10); alert(obj2 instanceof MyObject); // true- 到此,new 運(yùn)算的過程已經(jīng)描述得足夠清楚了,然而,如果你還想繼續(xù)了解內(nèi)部方法 [[Call]] 的詳情,不好意思,那就要牽涉到 JS 的函數(shù)閉包、作用域鏈,甚至深入到引擎對函數(shù)體的解析等內(nèi)容了,這些又是 JS 的另外一個(gè)難點(diǎn)系列,在此便不多談了。
| Constructs an object. Invoked via the new operator. Objects that implement this internal method are called constructors. |
| A string value indicating the kind of this object. |
| Executes code associated with the object. Invoked via a function call expression. Objects that implement this internal method are called functions. |
| The prototype of this object. |
轉(zhuǎn)載于:https://www.cnblogs.com/aaronjs/archive/2012/07/04/2575570.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的JS 对象机制深剖——new 运算符的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 扯一扯 之 面试经历
- 下一篇: SQL Server 2008 无法删除