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

JavaScript 原型與原型鏈詳情

 更新時間:2021年10月25日 15:22:30   作者:南玖  
這篇文章主要介紹了JavaScript 原型與原型鏈,JavaScript常被描述為一種基于原型的語言,對象以其原型為模板、從原型繼承屬性和放法。原型對象也可能擁有原型,并從中繼承屬性和方法,一層一層以此類推。這種關系常被稱為原型鏈,帶著簡單的了解看看下文內容具體介紹吧

前言:

JavaScript常被描述為一種「基于原型的語言」——每個對象都擁有一個「原型對象」,對象以其原型為模板、從原型繼承屬性和放法。原型對象也可能擁有原型,并從中繼承屬性和方法,一層一層以此類推。這種關系常被稱為「原型鏈」,它解釋了為何一個對象會擁有定義在其他對象中的屬性和方法。

準確的說,這些屬性和方法定義在Object的構造函數(shù)的prototype屬性上,而非對象實例本身。

四句話道破原型與原型鏈:

  • 每個函數(shù)(類)天生自帶一個屬性prototype,屬性值是一個對象,里面存儲了當前類供實例使用的屬性和方法 「(顯示原型)」
  • 在瀏覽器默認給原型開辟的堆內存中有一個constructor屬性:存儲的是當前類本身(⚠️注意:自己開辟的堆內存中默認沒有constructor屬性,需要自己手動添加)「(構造函數(shù))」
  • 每個對象都有一個__proto__屬性,這個屬性指向當前實例所屬類的原型(不確定所屬類,都指向Object.prototype)「(隱式原型)」
  • 當你試圖獲取一個對象的某個屬性時,如果這個對象本身沒有這個屬性,那么它會去它的隱式原型__proto__(也就是它的構造函數(shù)的顯示原型prototype)中查找?!福ㄔ玩湥?br />

構造函數(shù),原型與實例的關系:

每個構造函數(shù)(constructor)都有一個原型對象(prototype),原型對象(prototype)都包含一個指向構造函數(shù)(constructor)的指針,而實例(instance)都包含一個指向原型對象(__proto__)的內部指針

1、prototype(顯式原型)

每個函數(shù)都有一個prototype屬性

// 構造函數(shù)(類)
function Person(name){
    this.name = name
}
// new了一個實例 (對象)
var person = new Person('南玖')
console.log(person) //Person { name: '南玖' }
console.log(Person.prototype)  //構造函數(shù)(類)的原型 ----->對象
Person.prototype.age = 18  // 構造函數(shù)原型
console.log(person.age)  // 18


上面我們把這個函數(shù)Person的原型打印出來了,它指向的是一個對象,并且這個對象正是調用該構造函數(shù)而創(chuàng)建的實例的原型

上面這張圖表示的是構造函數(shù)與實例原型之間的關系,所以我們知道了構造函數(shù)的prototype屬性指向的是一個對象。

那實例與實例原型之間的關系又是怎樣的呢?這里就要提到__proto__屬性了

2、__proto__(隱式原型)

從上面四句話中我們可以知道這是每一個Javascript對象(除null)都具有的一個屬性,這個屬性會指向該對象的原型(也就是實例原型)

因為在JavaScript中沒有類的概念,為了實現(xiàn)類似繼承的方式,通過__proto__將對象和原型聯(lián)系起來組成原型鏈,的以讓對象訪問到不屬于自己的屬性。

那么我們就能夠證明實例與實例原型之間的關系

console.log(person.__proto__)  //實例(對象)的原型--->對象

console.log(person.__proto__ === Person.prototype)  //實例的原型與構造函數(shù)的原型相等

從上圖我們可以看出實例對象與構造函數(shù)都可以指向原型,那么原型能不能指向構造函數(shù)或者是實例呢?

3、constructor(構造函數(shù))

原型是沒有屬性指向實例的,因為一個構造函數(shù)可以創(chuàng)建多個實例對象;

從前面的四句話中我們知道「在瀏覽器默認給原型開辟的堆內存中有一個constructor屬性」,所以原型也是可以指向構造函數(shù)的,這個屬性就是「constructor

于是我們可以證明一下觀點:

console.log(Person.prototype.constructor) //實例的顯式原型的構造函數(shù)ƒ Person(name){this.name = name}
console.log(person.__proto__.constructor)  //實例的隱式原型的構造函數(shù) ƒ Person(name){this.name = name}
console.log(person.__proto__.constructor === Person.prototype.constructor)//true 實例原型的構造函數(shù)與類的構造函數(shù)相等
console.log(Person === Person.prototype.constructor)  //true


實例對象的__proto__是如何產生的?
我們知道當我們使用new 操作符時,生成的實例對象就擁有了__proto__屬性

function Foo() {}
// 這個函數(shù)時Function的實例對象
// function是一個語法糖
// 內部其實調用了new Function()


所以可以說,在new的過程中,新對象被添加了__proto__屬性并且鏈接到了構造函數(shù)的原型上。

4、new的原理

說簡單點可以分為以下四步:

  • 新建一個空對象
  • 鏈接原型
  • 綁定this,執(zhí)行構造函數(shù)
  • 返回新對象
function myNew() {
// 1.新建一個空對象
let obj = {}
// 2.獲得構造函數(shù)
let con = arguments.__proto__.constructor
// 3.鏈接原型
obj.__proto__ = con.prototype
// 4.綁定this,執(zhí)行構造函數(shù)
let res = con.apply(obj, arguments)
// 5.返回新對象
return typeof res === 'object' ? res : obj
}

5、原型鏈

說完了原型,我們再來看看什么是原型鏈?先來看一張圖:

這張圖中,由__proto__串起來的鏈式關系,我們就稱它為原型鏈

5.1 原型鏈的作用

原型鏈決定了JavaScript中繼承的實現(xiàn)方式,當我們訪問一個屬性時,它的查找機制如下:

  • 訪問對象實例屬性,有的話直接返回,沒有則通過__proto__去它的原型對象上查找
  • 原型對象上能找到的話則返回,找不到繼續(xù)通過原型對象的__proto__查找
  • 一直往下找,直到找到Object.prototype,如果能找到則返回,找不到就返回undefined,不會再往下找了,因為Object.prototype.__proto__是null,說明了Object是所有對象的原型鏈頂層了。

從圖中我們可以發(fā)現(xiàn),所有對象都可以通過原型鏈最終找到 Object.prototype ,雖然 Object.prototype 也是一個對象,但是這個對象卻不是 Object 創(chuàng)造的,而是引擎自己創(chuàng)建了 Object.prototype 。所以可以這樣說,所有實例都是對象,但是對象不一定都是實例。

5.2 構造函數(shù)的__proto__是什么呢?

由上面的原型鏈的解釋,我們應該能夠理解構造函數(shù)的__proto__的,在JavaScript中所有東西都是對象,那么構造函數(shù)肯定也是對象,是對象就有__proto__ 。

function Person(){}
console.log(Person.__proto__)
console.log(Function.prototype)
console.log(Person.__proto__===Function.prototype) // true


「這也說明了所有函數(shù)都是Function的實例」

那這么理解的話,Function.__proto__豈不是等于Function.prototype。。。。我們不妨來打印一下看看

Function.__proto__ === Function.prototype // true


打印出來確實是這樣的。難道 Function.prototype 也是通過 new Function() 產生的嗎?

答案是否定的,這個函數(shù)也是引擎自己創(chuàng)建的。首先引擎創(chuàng)建了 Object.prototype ,然后創(chuàng)建了 Function.prototype ,并且通過 __proto__ 將兩者聯(lián)系了起來。這里也很好的解釋了上面的一個問題,為什么 let fun = Function.prototype.bind() 沒有 prototype 屬性。因為 Function.prototype 是引擎創(chuàng)建出來的對象,引擎認為不需要給這個對象添加 prototype 屬性。

6、總結

  • Object 是所有對象的爸爸,所有對象都可以通過 __proto__ 找到它
  • Function 是所有函數(shù)的爸爸,所有函數(shù)都可以通過 __proto__ 找到它
  • Function.prototype Object.prototype 是兩個特殊的對象,他們由引擎來創(chuàng)建
  • 除了以上兩個特殊對象,其他對象都是通過構造器 new 出來的
  • 函數(shù)的 prototype 是一個對象,也就是原型
  • 對象的 __proto__ 指向原型, __proto__ 將對象和原型連接起來組成了原型鏈

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

相關文章

  • JS開發(fā)Blob和FileReader構造函數(shù)使用示例詳解

    JS開發(fā)Blob和FileReader構造函數(shù)使用示例詳解

    這篇文章主要為大家介紹了JS開發(fā)Blob和FileReader構造函數(shù)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • JS前端可視化GraphQL使用詳解

    JS前端可視化GraphQL使用詳解

    這篇文章主要為大家介紹了JS前端可視化GraphQL使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • JavaScript與JQuery框架基礎入門教程

    JavaScript與JQuery框架基礎入門教程

    這篇文章主要介紹了jQuery和JavaScript入門基礎知識學習指南,jQuery是當下最主流人氣最高的JavaScript庫,需要的朋友可以參考下
    2021-07-07
  • 使用async?await處理錯誤方法示例

    使用async?await處理錯誤方法示例

    這篇文章主要為大家介紹了使用async?await處理錯誤的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Javascript中綁定click事件的四種方式介紹

    Javascript中綁定click事件的四種方式介紹

    今天小編就為大家分享一篇關于Javascript中綁定click事件的四種方式介紹,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • 用JS創(chuàng)建一個錄屏功能

    用JS創(chuàng)建一個錄屏功能

    這篇文章主要介紹了利用JS創(chuàng)建一個錄屏功能,創(chuàng)建這個功能錢我們首先創(chuàng)建一個HTML文件,包含記錄按鈕和一個播放標簽,下面來看看創(chuàng)建的詳細過程
    2021-11-11
  • JS 里為什么會有 this

    JS 里為什么會有 this

    這篇文章主要介紹了JS 里為什么會有 this,文章主要從語言創(chuàng)造者(JS 之父的角度)來思考 this,我之前那篇講 this 的文章是從使用者的角度寫的,需要的朋友可以參考一下
    2021-10-10
  • 微信小程序 觸控事件詳細介紹

    微信小程序 觸控事件詳細介紹

    這篇文章主要介紹了微信小程序 觸控事件的相關資料,在開發(fā)微信小程序的時候,難免會用到這樣的功能,這里小編就幫大家梳理下相應的知識,需要的朋友可以參考下
    2016-10-10
  • javascript 操作cookies詳解及實例

    javascript 操作cookies詳解及實例

    這篇文章主要介紹了javascript 操作cookies詳解及實例的相關資料,需要的朋友可以參考下
    2017-02-02
  • JavaScript流程控制(循環(huán))

    JavaScript流程控制(循環(huán))

    這篇文章主要介紹了JavaScript流程控(循環(huán)),在程序中,一組被重復執(zhí)行的語句被稱之為循環(huán)體,能否繼續(xù)重復執(zhí)行,取決于循環(huán)的終止條件。由循環(huán)體及循環(huán)的終止條件組成的語句,被稱之為循環(huán)語句,更多詳細內容請需要的小伙伴參考下面文章的具體介紹
    2021-12-12

最新評論

隆化县| 长治县| 永嘉县| 晋中市| 湛江市| 裕民县| 民权县| 沅陵县| 萨迦县| 华亭县| 外汇| 万州区| 保定市| 霍林郭勒市| 苏尼特右旗| 庄浪县| 雷山县| 乐亭县| 沙湾县| 嘉黎县| 弥渡县| 德江县| 玉溪市| 马关县| 旺苍县| 江陵县| 乌兰浩特市| 昌江| 深水埗区| 汾阳市| 石棉县| 永福县| 长垣县| 西贡区| 蓝山县| 高清| 富川| 泾川县| 常山县| 怀来县| 玛纳斯县|