1. 原型 / 構(gòu)造函數(shù) / 實例
- 原型
(prototype)
: 一個簡單的對象,用于實現(xiàn)對象的 屬性繼承。原型對象即為當前實例對象的父對象。在 Firefox 和 Chrome 中,每個JavaScript
對象中都包含一個__proto__
(非標準)的屬性指向它爹(該對象的原型)悼院,可通過obj.__proto__
進行訪問。
函數(shù)的protype屬性
所有函數(shù)都有一個特別的屬性:prototype
: 顯式原型屬性
所有實例對象都有一個特別的屬性:__proto__
: 隱式原型屬性
顯式原型與隱式原型的關(guān)系 - 函數(shù)的
prototype
: 定義函數(shù)時被自動賦值, 默認值是一個空Object對象, 即為原型對象 - 實例對象的
__proto__
: 在創(chuàng)建實例對象時被自動添加, 并賦值為構(gòu)造函數(shù)的prototype
值 - 對象的隱式原型的值為其對應構(gòu)造函數(shù)的顯式原型的值
構(gòu)造函數(shù): 可以通過
new
來 新建一個對象 的函數(shù)咒循。實例: 通過構(gòu)造函數(shù)和
new
創(chuàng)建出來的對象据途,便是實例绞愚。-
三者關(guān)系: 實例通過
__proto__
指向原型,原型通過constructor
指向構(gòu)造函數(shù)颖医。
構(gòu)造函數(shù)/原型/實例對象的關(guān)系(圖解)
以Object
為例位衩,我們常用的Object
便是一個構(gòu)造函數(shù),因此我們可以通過它構(gòu)建實例便脊。
// 實例
const o1 = new Object()
則此時蚂四, 實例為o1
, 構(gòu)造函數(shù)為Object
光戈,我們知道哪痰,構(gòu)造函數(shù)擁有一個prototype
的屬性指向原型,因此原型為:
// 原型
const prototype = Object.prototype
這里我們可以來看出三者的關(guān)系:
實例.__proto__ === 原型
原型.constructor === 構(gòu)造函數(shù)
構(gòu)造函數(shù).prototype === 原型
2.原型鏈:
別名: 隱式原型鏈
原型鏈是由原型對象組成久妆,所有的實例對象都有__proto__
屬性晌杰,指向了創(chuàng)建該對象的構(gòu)造函數(shù)的原型,__proto__
將對象連接起來組成了一個鏈的結(jié)構(gòu)---->原型鏈筷弦。是一個用來實現(xiàn)繼承和共享屬性的有限的對象鏈肋演。屬性查找機制: 當查找對象的屬性時,先在自身屬性中查找烂琴,找到返回爹殊,如果實例對象自身不存在該屬性,則沿著原型鏈往上一級查找奸绷,找到時則輸出梗夸,不存在時,則繼續(xù)沿著原型鏈往上一級查找号醉,直至最頂級的原型對象
Object.prototype
反症,如還是沒找到,則輸出undefined
畔派;屬性修改機制: 只會修改實例對象本身的屬性铅碍,如果不存在,則進行添加該屬性线椰,如果需要修改原型的屬性時胞谈,則可以用:
b.prototype.x = 2
;但是這樣會造成所有繼承于該對象的實例的屬性發(fā)生改變憨愉。原型繼承:構(gòu)造函數(shù)的實例對象自動擁有構(gòu)造函數(shù)原型對象的屬性(方法)烦绳,利用的就是原型鏈。
方法一般定義在原型中, 屬性一般通過構(gòu)造函數(shù)定義在對象本身上莱衩。
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.setName = function (name) {
this.name = name
}
-
Object和Function
函數(shù)的顯示原型指向的對象默認是空Object
實例對象(但Object
不滿足)
console.log(Fn.prototype instanceof Object) // true
console.log(Object.prototype instanceof Object) // false
console.log(Function.prototype instanceof Object) // true
所有函數(shù)都是Function
的實例(包含Function
)
console.log(Function.__proto__===Function.prototype)
Object
的原型對象是原型鏈盡頭
console.log(Object.prototype.__proto__) // null
3.探索instanceof
- instanceof是如何判斷的?
- 表達式:
A instanceof B
- 如果B函數(shù)的顯式原型對象在A對象的原型鏈上, 返回
true
, 否則返回false
- Function是通過new自己產(chǎn)生的實例
console.log(Object instanceof Function);
console.log(Object instanceof Object);
console.log(Function instanceof Function);
console.log(Function instanceof Object);
function Foo() {}
console.log(Object instanceof Foo);