91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript原型鏈源碼分析

發布時間:2023-04-28 09:59:43 來源:億速云 閱讀:87 作者:zzz 欄目:開發技術

這篇文章主要講解了“JavaScript原型鏈源碼分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“JavaScript原型鏈源碼分析”吧!

    instanceof 簡介

    在 JavaScript 中,判斷一個變量的類型通常會用 typeof 運算符,在使用 typeof 運算符時采用引用類型存儲值會出現一個問題,無論引用的是什么類型的對象,它都返回 "object"。例如:

    var arr = new Array();
    console.log( typeof arr ); // object

    如果想要確定原型和實例之間的關系就需要用到 instanceof 操作符, 例如:

    var arr = new Array();
    var Fn = function() {};
    var foo = new Fn();
    console.log( arr instanceof Array ); // true
    console.log( arr instanceof Object ); // true
    console.log( foo instanceof Fn); // true
    console.log( foo instanceof Function ); // false
    console.log( foo instanceof Object ); // true

    Function instanceof Function ?

    console.log( String instanceof String );
    console.log( Function instanceof Function );
    console.log( Function instanceof Object );
    console.log( Object instanceof Function );
    console.log( Object instanceof Object );

    要解釋這個問題就需要了解 1.JavaScript 語言規范中是如何定義 instanceof 運算符的,2.JavaScript 原型繼承機制。

    instanceof 運算符的定義

    在 ECMAScript-262 中 instanceof 運算符的定義是這樣的。

    12.9.4 Runtime Semantics: InstanceofOperator(O, C)

    The abstract operation InstanceofOperator(O, C) implements the generic algorithm for determining if an object O inherits from the inheritance path defined by constructor C. This abstract operation performs the following steps:

    1. If Type(C) is not Object, throw a TypeError exception.
    2. Let instOfHandler be GetMethod(C,@@hasInstance).
    3. ReturnIfAbrupt(instOfHandler).
    4. If instOfHandler is not undefined, then
    a. Return ToBoolean(Call(instOfHandler, C, ?O?)).
    5. If IsCallable(C) is false, throw a TypeError exception.
    6. Return OrdinaryHasInstance(C, O).
    NOTE Steps 5 and 6 provide compatibility with previous editions of ECMAScript that did not use a @@hasInstance method to define the instanceof operator semantics. If a function object does not define or inherit @@hasInstance it uses the default instanceof semantics.

    7.3.19 OrdinaryHasInstance (C, O)

    The abstract operation OrdinaryHasInstance implements the default algorithm for determining if an object O inherits from the instance object inheritance path provided by constructor C. This abstract operation performs the following steps:

    1. If IsCallable(C) is false, return false.
    2. If C has a [[BoundTargetFunction]] internal slot, then
        a. Let BC be the value of C's [[BoundTargetFunction]] internal slot.
        b. Return InstanceofOperator(O,BC) (see 12.9.4).
    3. If Type(O) is not Object, return false.
    4. Let P be Get(C, "prototype").
    5. ReturnIfAbrupt(P).
    6. If Type(P) is not Object, throw a TypeError exception.
    7. Repeat
        a. Let O be `O.[[GetPrototypeOf]]()`.
        b. ReturnIfAbrupt(O).
        c. If O is null, return false.
        d. If SameValue(P, O) is true, return true.

    官網的定義非常晦澀,上面的翻譯成代碼大概就是:

    function instanceOf( L, R ) { //L 表示左表達式,R 表示右表達式
        var P = R.prototype; // 取 R 的顯示原型
        L = L.__proto__; // 取 L 的隱式原型
        while ( true ) { 
            if ( L === null ) return false;
            if ( P === L ) return true; 
            L = L.__proto__; 
        } 
    }

    再直接點的表達就是 instanceof 會一直在 obj 的原型鏈上查找,直到找到右邊那個構造函數的 prototype 屬性,或者為 null 的時候才停止。

    類似:

    obj.__proto__.__proto__ ... = Obj.prototype

    instanceof 會一直沿著隱式原型鏈 __proto__ 向上查找直到 obj.__proto__.__proto__ ...... === Obj.prototype 為止,如果找到則返回 true,也就是 obj 為 Obj 的一個實例。否則返回 false,obj 不是 Obj 的實例。

    JavaScript 原型繼承機制

    原型與原型鏈

    在 JavaScript 每個函數都有一個 prototype 屬性,該屬性存儲的就是原型對象。JavaScript 構造函數的繼承都是通過 prototype 屬性, 真正的原型鏈的實現是通過 __proto__ 實現的,__proto__其實是指向‘父類’的 prototype 屬性。例如:

    var Foo = function() {}
    var foo = new Foo;
    console.log(foo.__proto__ === Foo.prototype) // true
    console.log(Foo.__proto__ === Function.prototype) // true

    原型繼承

    JavaScript 是單繼承的,Object.prototype 是原型鏈的頂端,所有對象從它繼承了包括 valueOf、toString 等等方法和屬性。

    Object 本身是構造函數,繼承了 Function.prototype。 Function 也是對象,繼承了 Object.prototype。

    JavaScript原型鏈源碼分析

    Object instanceof Object

    ObjectL = Object, ObjectR = Object; 
    
    R = ObjectR.prototype = Object.prototype 
    L = ObjectL.__proto__ = Function.prototype 
    
    R != L 
    // 循環查找 L 是否還有 __proto__ 
    L = Function.prototype.__proto__ = Object.prototype 
    
    R == L 
    // 返回 true

    String instanceof String

    StringL = String, StringR = String;
    
    R = StringR.prototype = String.prototype
    L = StringL.__proto__ = Object.prototype
    
    R != L
    // 循環查找 L 是否還有 __proto__ 
    L = Object.prototype.__proto__ = null
    // 返回 false

    一切皆對象?

    常常說 JavaScript 中一切皆對象,那么就有這樣一個問題了:

    'string'.__proto__ === String.prototype // true
    'string' instanceof String // false

    按照上面的推導,'string' instanceof String 應該為 true,但是我們得到的卻是 false。 其實問題的關鍵在于:

    console.log(typeof 'string'); // string

    'string' 并不是一個 object 對象,MDN 上對 instanceof 的定義是:

    The instanceof operator tests whether an object in its prototype chain has the prototype property of a constructor.

     這樣又有一個問題了,既然字符串不是對象那為什么有對象才有的屬性和方法呢?

    var s1 = "string";
    var s2 = s1.substring(2);

    為了便于操作基本類型值,ECMAScript 還提供了 3 個特殊的引用類型: Boolean、Number 和 String。 實際上,每當讀取一個基本類型值的時候,后臺就會創建一個對應的基本包裝類型的對象,從而讓我們 能夠調用一些方法來操作這些數據。

    《JavaScript高級程序設計》中是這么解釋的:

    上面的例子其實當第二行代碼訪問 s1 時,訪問過程處于一種讀取模式,也就是要 從內存中讀取這個字符串的值。而在讀取模式中訪問字符串時,后臺都會自動完成: (1) 創建 String 類型的一個實例; (2) 在實例上調用指定的方法; (3) 銷毀這個實例。

    可以將以上三個步驟想象成是執行了下列 ECMAScript 代碼。

    var s1 = new String("some text");
    var s2 = s1.substring(2);
    s1 = null;

    《Javascript權威指南》里說:

    其實(包裝對象)在實現上并不一定創建或銷毀這個臨時對象,然而整個過程看起來是這樣的。

    這樣 Boolean、Number 是一樣的邏輯。還剩下兩種基本類型:null 和 undefined。

    undefined 當我們對變量只聲明沒有初始化時,輸出為 undefined,typeof undefined 返回的是 undefined 也不是 object 類型,所以 undefined 并不是任何對象的實例。

    null 表示的是空對象,雖然 typeof null 是 object,但是 null 和 undefined 一樣并沒有任何屬性和方法,在 instanceof 定義中也有判斷,如果類型不是 object(這個類型判斷并不是跟 typeof 返回值一樣),就返回 false。

    JavaScript原型鏈源碼分析

    感謝各位的閱讀,以上就是“JavaScript原型鏈源碼分析”的內容了,經過本文的學習后,相信大家對JavaScript原型鏈源碼分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    卓资县| 桐乡市| 山阳县| 万荣县| 垣曲县| 简阳市| 乌拉特后旗| 建水县| 安义县| 达孜县| 浑源县| 石渠县| 岢岚县| 资溪县| 洞口县| 洛川县| 延边| 天长市| 辉县市| 雷州市| 英吉沙县| 清苑县| 滨海县| 南通市| 阜新市| 闵行区| 大城县| 彩票| 名山县| 玉林市| 东丰县| 邯郸县| 通江县| 淮阳县| 军事| 濉溪县| 安西县| 正蓝旗| 宜良县| 友谊县| 怀宁县|