最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談JavaScript原型鏈

 更新時間:2023年04月24日 08:50:12   作者:前端小蜜蜂來也  
這篇文章主要為大家詳細介紹了JavaScript原型鏈,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

instanceof 簡介

在 JavaScript 中,判斷一個變量的類型通常會用 typeof 運算符,在使用 typeof 運算符時采用引用類型存儲值會出現(xiàn)一個問題,無論引用的是什么類型的對象,它都返回 "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 語言規(guī)范中是如何定義 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.

官網(wǎng)的定義非?;逎厦娴姆g成代碼大概就是:

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 的原型鏈上查找,直到找到右邊那個構造函數(shù)的 prototype 屬性,或者為 null 的時候才停止。

類似:

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

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

JavaScript 原型繼承機制

原型與原型鏈

在 JavaScript 每個函數(shù)都有一個 prototype 屬性,該屬性存儲的就是原型對象。JavaScript 構造函數(shù)的繼承都是通過 prototype 屬性, 真正的原型鏈的實現(xiàn)是通過 __proto__ 實現(xiàn)的,__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 本身是構造函數(shù),繼承了 Function.prototype。 Function 也是對象,繼承了 Object.prototype。

Object instanceof Object

ObjectL = Object, ObjectR = Object; 

R = ObjectR.prototype = Object.prototype 
L = ObjectL.__proto__ = Function.prototype 

R != L 
// 循環(huán)查找 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
// 循環(huán)查找 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。 實際上,每當讀取一個基本類型值的時候,后臺就會創(chuàng)建一個對應的基本包裝類型的對象,從而讓我們 能夠調用一些方法來操作這些數(shù)據(jù)。

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

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

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

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

《Javascript權威指南》里說:

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

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

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

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

寫在最后

如果這篇文章對你有幫助,請不要吝嗇你手中的贊??!你的鼓勵將是我不斷分享的動力!??

到此這篇關于淺談JavaScript原型鏈的文章就介紹到這了,更多相關JavaScript原型鏈內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • JS實現(xiàn)的自定義map方法示例

    JS實現(xiàn)的自定義map方法示例

    這篇文章主要介紹了JS實現(xiàn)的自定義map方法,結合實例形式分析了javascript自定義map相關的json數(shù)組定義、遍歷、添加、刪除、讀取等相關操作技巧,需要的朋友可以參考下
    2019-05-05
  • JavaScript單一職責原則深入分析

    JavaScript單一職責原則深入分析

    這篇文章主要介紹了理解JavaScript單一職責原則,單一職責原則(SRP:Single?responsibility?principle)又稱單一功能原則,面向對象五個基本原則(SOLID)之一,下文更多相關介紹感興趣的小伙伴可以參考一下
    2022-08-08
  • 微信小程序實現(xiàn)banner圖輪播效果

    微信小程序實現(xiàn)banner圖輪播效果

    這篇文章主要為大家詳細介紹了微信小程序實現(xiàn)banner圖輪播效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • JavaScript中一些特殊的字符運算

    JavaScript中一些特殊的字符運算

    這篇文章主要介紹了JavaScript中一些特殊的字符運算的相關資料,需要的朋友可以參考下
    2017-08-08
  • 基于JavaScript實現(xiàn)十五拼圖代碼實例

    基于JavaScript實現(xiàn)十五拼圖代碼實例

    這篇文章主要介紹了基于JavaScript實現(xiàn)十五拼圖代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • js發(fā)送短信倒計時的簡單實現(xiàn)方法

    js發(fā)送短信倒計時的簡單實現(xiàn)方法

    下面小編就為大家?guī)硪黄猨s發(fā)送短信倒計時的簡單實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • javascript日期格式化方法匯總

    javascript日期格式化方法匯總

    本文給大家匯總介紹了javascript格式化日期時間的幾種常用方法,個人對最后一種個性化輸出時間比較有興趣,基本上只要項目中能用到都是使用這種,推薦給小伙伴們。
    2015-10-10
  • js實現(xiàn)點擊切換checkbox背景圖片的簡單實例

    js實現(xiàn)點擊切換checkbox背景圖片的簡單實例

    下面小編就為大家?guī)硪黄猨s實現(xiàn)點擊切換checkbox背景圖片的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 關于JS判斷圖片是否加載完成且獲取圖片寬度的方法

    關于JS判斷圖片是否加載完成且獲取圖片寬度的方法

    本篇文章小編為大家介紹,關于JS判斷圖片是否加載完成且獲取圖片寬度的方法,有需要的朋友可以參考一下
    2013-04-04
  • 一個JS函數(shù)搞定網(wǎng)頁標題(title)閃動效果

    一個JS函數(shù)搞定網(wǎng)頁標題(title)閃動效果

    這篇文章主要介紹了使用JS函數(shù)實現(xiàn)網(wǎng)頁標題(title)閃動效果的代碼,需要的朋友可以參考下
    2014-05-05

最新評論

肃宁县| 济宁市| 镇原县| 大冶市| 贡嘎县| 板桥市| 英吉沙县| 资阳市| 麻栗坡县| 平泉县| 新河县| 垦利县| 民勤县| 吴堡县| 儋州市| 民县| 邹城市| 晋宁县| 桂林市| 湖南省| 大冶市| 锦州市| 五家渠市| 长武县| 双牌县| 杭州市| 乌什县| 合川市| 巴彦淖尔市| 宜阳县| 广平县| 昂仁县| 获嘉县| 乌苏市| 大田县| 通化县| 建水县| 开原市| 黄石市| 洛川县| 宁波市|