javaScript原型和原型鏈

来源:https://www.cnblogs.com/akari16/archive/2022/06/29/16422099.html
-Advertisement-
Play Games

前言 在瞭解原型和原型鏈之前,我們先瞭解一部分概念,constructor,prototype,proto。 constructor 在之前判斷數據類型的文章: javaScript常見數據類型檢查校驗 有提到過關於構造函數的屬性constructor constructor 的是返回創建實例對象的 ...


前言

在瞭解原型和原型鏈之前,我們先瞭解一部分概念,constructor,prototype,proto

constructor

在之前判斷數據類型的文章: javaScript常見數據類型檢查校驗

有提到過關於構造函數的屬性constructor

constructor 的是返回創建實例對象的 構造函數的引用,這個屬性的值是對函數本身的引用,而不是一個包含函數名稱的字元串
具體用法:構造函數.prototype.constructor()

function constructorFn() {
  this.name = "11";
}

console.log(constructorFn.constructor); // Function

let a = new constructorFn();
console.log(a.constructor);
// ƒ constructorFn() {
  this.name = "11";
}

原型prototype


console.log(Object.prototype);

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
{

    constructor: ƒ Object()
    hasOwnProperty: ƒ hasOwnProperty()
    isPrototypeOf: ƒ isPrototypeOf()
    propertyIsEnumerable: ƒ propertyIsEnumerable()
    toLocaleString: ƒ toLocaleString()
    toString: ƒ toString()
    valueOf: ƒ valueOf()
    __defineGetter__: ƒ __defineGetter__()
    __defineSetter__: ƒ __defineSetter__()
    __lookupGetter__: ƒ __lookupGetter__()
    __lookupSetter__: ƒ __lookupSetter__()
    __proto__: (...)
    get __proto__: ƒ __proto__()
    set __proto__: ƒ __proto__()

}

在js當中,每個函數或者方法都有一個特殊的,並且是預設的屬性叫作原型(prototype),它是一個對象,這個對象包含了這個方法自帶的一些屬性和方法。

原型鏈 proto

function constructorFun() {}
constructorFun.prototype.testName = "constructorFun";
let newFun = new constructorFun();

// newFun
console.log(newFun);
console.log(newFun.testName); // 通過__proto__查找 輸出: constructorFun
console.log(newFun.constructor);  // ƒ constructorFun() {}
console.log(newFun.__proto__);  // {testName: 'constructorFun', constructor: ƒ}
console.log(newFun.prototype);  // undefined
console.log(newFun.prototype.__proto__); // Error in created hook: "TypeError: Cannot read property '__proto__' of undefined"

通過上述代碼我們可以看到,prototype這個對象裡面,包含了一個__proto__的屬性,這個屬性就是原型鏈的關鍵,

  • 當newFun用過new操作符,繼承構造函數constructorFun的時候,testName,同時通過newFun.__proto__我們可以知道,newFun沒有自己的name的時候,會通過__proto__不斷地往上查找,直到查找到相關屬性,如果不存在則為undefined

  • 在JavaScript 中只有一種結構:對象。每個實例對象(object)都有一個私有屬性(稱之為 proto )指向它的構造函數的原型對象(prototype)。該原型對象也有一個自己的原型對象(proto),層層向上直到一個對象的原型對象為 null。根據定義,null 沒有原型,並作為這個原型鏈中的最後一個環節。(斷言出自 MDN https://developer.mozilla.org/

從原型鏈查找到null的過程

構造函數

function constructorFun() {}
constructorFun.prototype.testName = "constructorFun";
let newFun = new constructorFun();

// newFun
console.log(newFun);
console.log(newFun.testName); // 通過__proto__查找 輸出: constructorFun
console.log(newFun.constructor);  // ƒ constructorFun() {}
console.log(newFun.__proto__);  // {testName: 'constructorFun', constructor: ƒ}
console.log(newFun.prototype);  // undefined
console.log(newFun.prototype.__proto__); // Error in created hook: "TypeError: Cannot read property '__proto__' of undefined"

  • 使用new操作符實例化的方法,沒有自己的原型對象,並且通過__proto__可以向上查找構造函數的屬性和方法,以及構造函數。
  • 實例化方法可以通過constructor屬性,獲取構造函數本身
// constructorFun
console.log(constructorFun.constructor);  // ƒ Function() { [native code] }
console.log(constructorFun.__proto__ === Function.prototype); // true
console.log(constructorFun.prototype);  // {testName: 'constructorFun', constructor: ƒ}testName: "constructorFun"constructor: ƒ constructorFun()[[Prototype]] ...}
console.log(constructorFun.prototype.constructor);  // ƒ constructorFun() {}
console.log(constructorFun.prototype.__proto__ === Object.prototype); // true
  • 構造函數constructorFun的屬性constructor為Function,原型鏈向上查找的時候,構造函數的__proto__ → Function的原型prtotype
  • constructorFun的原型對象的__proto__是對象的原型
// Function
console.log(Function.constructor);  // ƒ Function() { [native code] }
console.log(Function.__proto__);    // ƒ () { [native code] }
console.log(Function.prototype);    // ƒ () { [native code] }
console.log(Function.prototype.constructor);  // ƒ Function() { [native code] }
console.log(Function.prototype.__proto__ === Object.prototype); // true
// Object
console.log(Object.constructor);  // ƒ Function() { [native code] }
console.log(Object.__proto__);  // ƒ () { [native code] }
console.log(Object.prototype);  // constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …
console.log(Object.prototype.constructor);  // ƒ Object() { [native code] }
console.log(Object.prototype.__proto__);  // null

字面量創建對象

let parent = {name:1}
// parent

console.log(parent.constructor); // ƒ Object() { [native code] }
console.log(parent.__proto__);  // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
console.log(parent.prototype);  // undefined
// console.log(parent.prototype.__proto__); // Error in created hook: "TypeError: Cannot read property '__proto__' of undefined"

// Object
console.log(Object.constructor); // ƒ Function() { [native code] }
console.log(Object.__proto__);  // ƒ () { [native code] }
console.log(Object.prototype);  // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
console.log(Object.prototype.constructor);  // ƒ Object() { [native code] }
console.log(Object.prototype.__proto__);  // null


通過以上代碼查找,我們可以畫出對應的關係圖

原型圖

總結:

  • 原型prototype和原型鏈查找__proto__,constructor構成了原型鏈,通過這些屬性和方法可以層層網上查找一直到null
  • 構造函數實例化方法,可以通過原型鏈的形式向上查找到對應屬性(這個屬性存在的前提下),這裡的知識點還包含了new實例的過程中,繼承方面的知識
  • 使用原型鏈和原型,我們可以進行封裝一下構造方法,還有一些插件,我們在閱讀一下框架源碼或者插件源碼的時候,都能看到原型和構造函數相關的代碼。
  • 原型和原型鏈的知識從概念上並不太好理解或者說有點晦澀難懂,可以試著去寫一些實例化對象和方法,去查找原型上的方法
  • 並且在開發過程中如果涉及到面向對象編程或者運用較多的話,可以加深我們的理解
  • 類似數組以及Function等構造函數,我們可以通過繼承,在原型鏈上擴展一些通用的utils方法

以上就是js中原型和原型鏈概念的簡單解析,有任何問題歡迎留言,後續的文章整理然後作為補充。

文章博客地址:javaScript原型和原型鏈

源碼地址

歡迎關註公眾號:程式員布歐,不定期更新一些文章

創作不易,轉載請註明出處和作者。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 測試環境: GTID的主從複製,主庫(9900)——》備庫(9909),存在測試庫表: 9900_db1庫:t1、t2、t3、t4、t5表 9900_db2庫:t6、t7、t8、t9、t10表 1、replicate-do-db參數: --replicate-do-db=name,只同步指定的資料庫 ...
  • 體驗簡介 場景將提供一臺配置了CentOS 8.5操作系統的ECS實例(雲伺服器)。通過本教程的操作帶您體驗如何使用PolarDB-X與Flink搭建一個實時數據鏈路,模擬阿裡巴巴雙十一GMV大屏。 實驗準備 1. 創建實驗資源 開始實驗之前,您需要先創建ECS實例資源。 在實驗室頁面,單擊創建資源 ...
  • 一、配置簽名信息 /** * 1.testApplicationId用於配置測試App的包名,預設情況下是applicationId + ".test".一般情況下預設即可,他也是 * ProductFlavor的一個屬性,方法原型為 * public ProductFlavor setTestAp ...
  • 6月28日,HDD·HMS Core. Sparkle影音娛樂線上沙龍在各大直播平臺與開發者們見面。本次線上沙龍圍繞影音娛樂行業現狀觀察和趨勢、用戶數據洞察分析以及HMS Core影音娛樂行業解決方案等多個話題展開,與開發者共同探討如何打造豐富有趣的影音娛樂體驗。 音視頻逐漸成為大眾化的表達語言,與 ...
  • yarn 由於yarn的全局安裝位置與npm不同,所以要配置yarn的全局安裝路徑到環境變數中,否則全局安裝的包不起作用具體操作如下 咱裝 yarn 分別執行 yarn global命令, yarn global bir 命令 將上述兩步返迴路徑配置到電腦環境中變變數中即可 xxxx 表示要安裝的東 ...
  • AntDesignVue --tree 樹形插件自定義圖標。 index.vue樹形區域的代碼如下,重點就是①那個“showIcon” 參數要等於“true”;②寫幾個img標簽顯示你自定義的圖標,img標簽加“slot”屬性。 <a-tree showIcon="true" showLine > ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一、談談你對MVVM的理解? 映射關係簡化,隱藏controller MVVM在MVC的基礎上,把控制層隱藏掉了。 Vue不是一個MVVM框架,它是一個視圖層框架。 ViewModal是一個橋梁,將數據和視圖進行關聯。 二、談談你對Vue ...
  • 今天,遇到了一個很有意思的問題,一名群友問我,僅僅使用 CSS,能否實現這樣一種響應式的佈局效果: 簡單解析一下效果: 在屏幕視口較為寬時,表現為一個整體 Table 的樣式 而當屏幕視口寬度較小時,原 Table 的每一行數據單獨拆分為一個 Table 進行展示 很有意思的一個響應式佈局,讓信息在 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...