日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JS 对象机制深剖——new 运算符

發(fā)布時(shí)間:2025/7/25 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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:
  • Evaluate NewExpression.
  • Call GetValue(Result(1)).
  • If Type(Result(2)) is not Object, throw a TypeError exception.
  • If Result(2) does not implement the internal?[[Construct]]?method, throw a TypeError exception.
  • Call the [[Construct]] method on Result(2), providing no arguments (that is, an empty list of arguments).
  • Return Result(5).
    • 注意到,這段定義中的 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:
  • Evaluate MemberExpression.
  • Call GetValue(Result(1)).
  • Evaluate Arguments, producing an internal list of argument values (11.2.4).
  • If Type(Result(2)) is not Object, throw a TypeError exception.
  • If Result(2) does not implement the internal [[Construct]] method, throw a TypeError exception.
  • Call the [[Construct]] method on Result(2), providing the list Result(3) as the argument values.
  • Return Result(6).
  • 考察 [[Construct]] 內(nèi)部方法,先給出語言規(guī)范的描述:

    When the [[Construct]] property for a Function object F is called, the following steps are taken:
  • Create a new native ECMAScript object.
  • Set the?[[Class]]?property of Result(1) to “Object”.
  • Get the value of the prototype property of the F.
  • If Result(3) is an object, set the?[[Prototype]]?property of Result(1) to Result(3).
  • If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as described in 15.2.3.1.
  • Invoke the?[[Call]]?property of F, providing Result(1) as the this value and providing the argument list passed into [[Construct]] as the argument values.
  • If Type(Result(6)) is Object then return Result(6).
  • Return Result(1).
    • 引擎將先創(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)系列,在此便不多談了。
    附錄PROPERTYDESCRIPTION[[CONSTRUCT]][[CLASS]][[CALL]][[PROTOTYPE]]
    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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。