深入理解JavaScript中的繼承:原型鏈篇

来源:http://www.cnblogs.com/envision/archive/2017/11/06/JavaScript.html
-Advertisement-
Play Games

用另一種視角去理解JavaScript的原型鏈,明白__proto__跟prototype的本質。 ...


一、何為原型鏈

  原型是一個對象,當我調用一個對象的方法時,如果該方法沒有在對象裡面,就會從對象的原型去尋找。JavaScript就是通過層層的原型,形成原型鏈。

二、誰擁有原型

  任何對象都可以有原型,當我們創建對象的時候,會自動為對象添加一個屬性,這個屬性就是原型,我們無法訪問到他,但在firefox和chrome中可以通過一個非標準的屬性__proto__(雙下劃線)來訪問到原型(或通過Object.getPrototypeOf來訪問)。

三、理解原型鏈

  我們先從以下代碼入手

  var foo = {};
  console.log(foo.toString()); // [object Object]  
  console.log(foo.__proto__); // object { ... } 這裡指向Object.prototype

  foo裡面明明沒有toString方法,但我卻能調用,這就是原型鏈的作用。當我調用foo.toString時,由於在裡面找不到toString方法,那麼我從__proto__屬性裡面去找,找到後並調用。上面的代碼中我們就是從Object.prototype中找到了toString方法。你可能會很困惑,prototype是什麼?我們不要被prototype所迷惑,他只是一個存放屬性的容器而已,你可以如下這樣做來實現繼承(但儘量不要這麼做)

function Bar() {}
Bar.test = {
  say: function () {
       console.log('say test');     
    }  
}

var foo = new Bar();
foo.say(); // 報錯

// 改變繼承的對象

foo.__proto__ = Bar.test;
foo.say() // say test

 

 

 

  在上面的代碼中我們通過new的形式來創建一個對象,在new的過程中對象會將__proto__指向函數的prototype,由於prototype中是沒有say函數的,所以調用會報錯,但是之後我們強行改變了繼承的對象,將foo的繼承對象改為Bar.test,所以我們就能調用say函數了。


 

  我想你已經明白個大概了,prototype事實上並沒有什麼特殊的,硬要說有什麼特殊的話,他只是被JavaScript預設為原型屬性的存放點而已,他本質上只是個對象,原型鏈的重點就在於__proto__,你可以試著把__proto__當作橋梁,當我在對象內部找不到屬性時,我就會通過這座橋梁到對面的對象里去尋找屬性,直到找到為止或者對象里沒有橋梁時才停下來。JavaScript就是通過這樣的方式來形成原型鏈,實現繼承的關係。

  最後說一下,__proto__只是方便我們查看對象的原型而已,大家不要通過修改__proto__來實現繼承的關係,而是要用如構造函數之類的方式來實現繼承,這個我會放到以後的文章去說。

(ps:可能有動手能力強的同學會自己去測試,發現__proto__裡面也有__proto__,一直迴圈下去,無窮無盡,但事實上你去獲取的時候你會發現Object.__proto__.__proto__.__proto__的值是null,也就是沒有原型。

 

  

 


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

-Advertisement-
Play Games
更多相關文章
  • name=[ 'coco', 'liux', 'zhangyq', 'liufupengdozhao']# 使用rang()方法for i in range(0,len(name)): print(i,name[i])# 上面的方法有些累贅,使用內置enumerrate函數會有更加直接for i i... ...
  • 上一篇文章直接就被移除首頁了,這次來點大家都能懂的乾貨. 需求 之前做一個winform的工具時候有以下幾個需求1. 主窗體(或者叫平臺)可以安裝若幹類型的插件。2. 插件關閉時候需要保存狀態。3. 插件載入的時候可以載入上次關閉的配置。4. 插件中的配置可以切換。5. 主窗體本身保存當前插件,並且 ...
  • Hitchhiker是一個在github上開源的項目,被善友大哥收錄到了它的微服務工具包里《開源的 Restful Api 集成測試工具 Hitchhiker》,同時源代碼也開源到了github上https://github.com/brookshi/Hitchhiker 多樣化的部署 deploy ...
  • 工廠模式(Factory Pattern) 1,Shape介面的定義 2,Circle實現Shape介面 3,Rectangle實現Shape介面 4,Square實現Shape介面 5,工廠方法類ShapeFactory 6,工廠的使用Demo ...
  • 簡介(Introduction) <! 出這邊文章的目的,及如何更好地閱讀這篇文章 之前學習 "Java8實戰" 時,遇到一個很好的策略模式示例。便想著藉著這個示例結合反饋式的方法來,學習策略設計模式,也以便後面反覆琢磨學習。 首先我們通過練習,逐步寫出符合相應需求的代碼,再根據需求進行改進、比較、 ...
  • 1、使用position中的absolute要與relative配套使用,如果不使用relative時預設absolute會用整個視窗作為參照物;如果relative放在absolute的父級標簽上,則absolute會以父級塊標簽作為參照物調整位置,absolute要使用top、left、righ ...
  • function Stack() { this.dataStore = []; //存儲棧元素 } Stack.prototype = { constructor: Stack, push: function(element) { this.dataStore.push(element) }, po... ...
  • 共同點:split與join函數通常都是對字元或字元串的操作; 兩者的區別:(1)split()用於分割字元串,返回一個數組,例如 var string=“hello world?name=xiaobai”; var splitString = string.split("?"); console. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...