javaScript中的原型鏈
認識物件的原型–隱式原型
? JavaScript當中每個物件都有一個特殊的內置屬性 [[prototype]](這個就是__proto__隱式原型),這個特殊的物件可以指向另外一個物件,
那么這個物件有什么用呢?
- 當我們通過參考物件的屬性key來獲取一個value時,它會觸發 [[Get]]的操作;
- 這個操作會首先檢查該物件是否有對應的屬性,如果有的話就使用它;
- 如果物件中沒有該屬性,那么會訪問物件[[prototype]]內置屬性指向的物件上的屬性;
那么如果通過字面量直接創建一個物件,這個物件也會有這樣的屬性嗎?如果有,應該如何獲取這個屬性呢?
? 答案是有的,只要是物件都會有這樣的一個內置屬性;
獲取的方式有兩種:
- 方式一:通過物件的 proto 屬性可以獲取到(但是這個是早期瀏覽器自己添加的,存在一定的兼容性題);
- 方式二:通過 Object.getPrototypeOf 方法可以獲取到;
函式的原型 prototype–顯式原型
那么我們知道上面的東西對于我們的建構式創建物件來說有什么用呢?它的意義是非常重大的,接下來我們繼續來探討; 這里我們又要引入一個新的概念:所有的函式都有一個prototype的屬性:

你可能會有問題,是不是因為函式是一個物件,所以它有prototype的屬性呢?不是的,因為它是一個函式,才有了這個特殊的屬性;而不是它是一個物件,所以有這個特殊的屬性;

再看new運算子
我們前面講過new關鍵字的步驟如下:
- 1.在記憶體中創建一個新的物件(空物件);
- 2.這個物件內部的[[prototype]]屬性會被賦值為該建構式的prototype屬性;(后面詳細講);
那么也就意味著我們通過Person建構式創建出來的所有物件的[[prototype]]屬性都指向Person.prototype:

創建物件的記憶體表現

賦值為新的物件

constructor屬性
? 事實上原型物件上面是有一個屬性的:constructor默認情況下原型上都會添加一個屬性叫做constructor,這個constructor指向當前的建構式物件

創建物件 – 建構式和原型組合
function Person(name, age, height, address) {
this.name = name
this.age = age
this.height = height
this.address = address
}
Person.prototype.eating = function() {
console.log(this.name + "在吃東西~")
}
Person.prototype.running = function() {
console.log(this.name + "在跑步~")
}
var p1 = new Person("why", 18, 1.88, "北京市")
var p2 = new Person("kobe", 20, 1.98, "洛杉磯市")
p1.eating()
p2.eating()
JavaScript中的類和物件
當我們撰寫如下代碼的時候,我們會如何來稱呼這個Person呢?
在JS中Person應該被稱之為是一個建構式;
從很多面向物件語言過來的開發者,也習慣稱之為類,因為類可以幫助我們創建出來物件p1、p2;
如果從面向物件的編程范式角度來看,Person確實是可以稱之為類的;
function Person(){
}
const p=new Person()
面向物件的特性 – 繼承
面向物件有三大特性:封裝、繼承、多型
- 封裝:我們前面將屬性和方法封裝到一個類中,可以稱之為封裝的程序;
- 繼承:繼承是面向物件中非常重要的,不僅僅可以減少重復代碼的數量,也是多型前提(純面向物件中);
- 多型:不同的物件在執行時表現出不同的形態;
那么這里我們核心講繼承,
? 那么繼承是做什么呢?繼承可以幫助我們將重復的代碼和邏輯抽取到父類中,子類只需要直接繼承過來使用即可,那么JavaScript當中如何實作繼承呢?不著急,我們先來看一下JavaScript原型鏈的機制;再利用原型鏈的機制實作一下繼承;
JavaScript原型鏈
? 在真正實作繼承之前,我們先來理解一個非常重要的概念:原型鏈,我們知道,從一個物件上獲取屬性,如果在當前物件中沒有獲取到就會去它的原型上面獲取:

Object的原型
那么什么地方是原型鏈的盡頭呢?比如第三個物件是否也是有原型__proto__屬性呢?

我們會發現它列印的是 [Object: null prototype] {}
- 事實上這個原型就是我們最頂層的原型了
- 從Object直接創建出來的物件的原型都是 [Object: null prototype] {},
那么我們可能會問題: [Object: null prototype] {} 原型有什么特殊嗎?
- 特殊一:該物件有原型屬性,但是它的原型屬性已經指向的是null,也就是已經是頂層原型了;
- 特殊二:該物件上有很多默認的屬性和方法;

原型鏈關系的記憶體圖

Object是所有類的父類
從我們上面的Object原型我們可以得出一個結論:原型鏈最頂層的原型物件就是Object的原型物件

原型繼承關系

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/385621.html
標籤:其他
下一篇:HTML小專案之雙色球
