欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript深入淺出__proto__和prototype

 更新時(shí)間:2022年05月24日 17:17:42   作者:??SilentLove????  
這篇文章主要介紹了JavaScript深入淺出__proto__和prototype,文章基于JavaScript的相關(guān)資料展開詳細(xì)的內(nèi)容介紹。具有一定的參考價(jià)值,需要的小伙伴可以參考一下

首先我們先記住幾個(gè)知識(shí)點(diǎn):

  • 每個(gè)函數(shù)都有一個(gè)prototype屬性
  • 每個(gè)對(duì)象都有一個(gè)__proto__屬性(null除外)
  • 函數(shù)也是對(duì)象

構(gòu)造函數(shù)和實(shí)例

首先我們通過下面的例子了解些基本的概念

function Person() {
}
var person1 = new Person()
  • 使用 new 創(chuàng)建對(duì)象的函數(shù)就是構(gòu)造函數(shù)、創(chuàng)建出的對(duì)象就是構(gòu)造函數(shù)的實(shí)例對(duì)象
  • 本例中:Person 就是一個(gè)構(gòu)造函數(shù),我們使用 new 創(chuàng)建了一個(gè)實(shí)例對(duì)象 person1
  • 構(gòu)造函數(shù)大寫只是約定俗成的習(xí)慣,實(shí)際上任何可以使用 new 運(yùn)算符的函數(shù)都可以是構(gòu)造函數(shù)

prototype

function Person() {
}
Person.prototype.name = 'Person'
var person1 = new Person()
console.log(person1.name) // Person
console.log(Person.prototype)

  • Person 的 prototype 屬性指向的是 Person.prototype 的原型對(duì)象
  • 在這個(gè)例子中可以看出,person1 本身并沒有 name 屬性,訪問的其實(shí)是 Person 中prototype 的 name
  • 從這里可以得出必然有一種關(guān)系把person1Person關(guān)聯(lián)起來(lái),使得person1可以訪問到Person中prototype的屬性值

帶著上面的疑問我們繼續(xù)下面的例子

__proto__prototype的關(guān)系

function Person() {
}
Person.prototype.name = 'Person'
var person1 = new Person()
console.log(person1)
console.log(person1.__proto__.name === Person.prototype.name) // true
console.log(person1.__proto__ === Person.prototype) // true

一開始我們就提到,每個(gè)對(duì)象都有一個(gè)__proto__屬性(null除外),通過這個(gè)例子我們發(fā)現(xiàn)person1的__proto__屬性下有個(gè)name屬性,正好是Person.prototype.name的值,由此我們可以看出實(shí)例person1是通過__proto__訪問的構(gòu)造函數(shù)Person的prototype屬性

根據(jù)上面的結(jié)論,我們很容易得出以下關(guān)系圖

由此我們很容易得出,多個(gè)示例對(duì)象之間通過__proto__進(jìn)行關(guān)聯(lián),可以通過__proto__共享Person.prototype上的屬性

constructor

既然構(gòu)造函數(shù)和實(shí)例都可以指向原型,那么原型是否有屬性指向構(gòu)造函數(shù)或者實(shí)例呢? 通過上面的例子,我們發(fā)現(xiàn)除了__proto__,還有一個(gè)constructor屬性

function Person() {
}
Person.prototype.name = 'Person'
var person1 = new Person()
console.log(Person) // ? Person() {}
console.log(Person.prototype.constructor) // ? Person() {}
console.log(person1.__proto__.constructor) // ? Person() {}
// 由此我們發(fā)現(xiàn)`constructor`屬性指向的是Person構(gòu)造函數(shù)本身,不難得出以下結(jié)論
console.log(Person === Person.prototype.constructor) // true

由此我們可以得出以下關(guān)系圖:

原型對(duì)象的原型

  • 原型也是一個(gè)對(duì)象,一開始就提到,每個(gè)對(duì)象都有一個(gè)__proto__屬性(null除外),因此原型對(duì)象也是有__proto__
  • 實(shí)際上原型對(duì)象就是通過 Object 構(gòu)造函數(shù)生成的
var prototypeObj = new Object()
console.log(prototypeObj.__proto__ === Object.prototype) // true

到此我們可以得出一個(gè)新的關(guān)系圖

到這里大家可能就有疑惑了,這樣不就無(wú)限循環(huán)了嗎,Object.protoType__proto__又是什么呢?

console.log(Object.protoType.__proto__) // null
console.log(Object.protoType.__proto__ === null) // true

所以 Object.prototype 為null,屬性查找到這里也就結(jié)束了

原型鏈

由上面的例子我們得知,在查找對(duì)象的屬性時(shí),優(yōu)先查找實(shí)例對(duì)象的屬性,查找不到時(shí)就會(huì)通過__proto__ 查找 prototype原型對(duì)象的屬性,還查不到會(huì)通過prototype的__proto__繼續(xù)查找,直到Object.protoType.__proto__為止

圖中由__proto__組成的紅色鏈路就是我們所說(shuō)的原型鏈

擴(kuò)展知識(shí)

關(guān)于 Object 和 Function

既然函數(shù)也是對(duì)象,對(duì)象都有 __proto__ ,那么 Object 和 Function 的 __proto__ 屬性又是什么呢?

  • Object對(duì)象是由Function構(gòu)造函數(shù)創(chuàng)建的
  • Function的原型對(duì)象Function.prototype是由Object構(gòu)造函數(shù)創(chuàng)建的
  • 【按照原型的定義,可以理解為】Function對(duì)象是由Function構(gòu)造函數(shù)本身創(chuàng)建

根據(jù)原型鏈的相關(guān)知識(shí),實(shí)例對(duì)象的 __proto__ 指向構(gòu)造函數(shù)的原型對(duì)象 prototype

// Object對(duì)象由Function構(gòu)造函數(shù)創(chuàng)建
Object.__proto__ === Function.prototype // true
// Function的原型對(duì)象`Function.prototype`是由Object創(chuàng)建
Function.prototype.__proto__ === Object.prototype // true
// Function由Function本身創(chuàng)建(按照原型的定義可以簡(jiǎn)單這么去理解,這里不做深究)
Function.__proto__ === Function.prototype // true
Object.getPrototypeOf(Function) === Function.prototype // true

由此我們可以得出最終的關(guān)系圖:

關(guān)于 getPrototypeOf、isPrototypeOfinstanceof

function Person() {
}
var person1 = new Person()
// Object.getPrototypeOf(obj) 返回obj實(shí)例對(duì)象的原型(obj.__proto__)
console.log(Object.getPrototypeOf(person1) === Person.prototype) // true
// Object.isPrototypeOf(obj),如果obj.__proto__和Object.prototype在一條原型鏈上(或者理解為Object為obj的構(gòu)造函數(shù)或父級(jí)構(gòu)造函數(shù)),則返回true
console.log(Object.prototype.isPrototypeOf(person1)) // true
console.log(Object.prototype.isPrototypeOf(Person.prototype)) // true
console.log(Person.prototype.isPrototypeOf(person1)) // true
// (obj instanceof Object) 同isPrototypeOf類似,obj.__proto__和Object.prototype在一條原型鏈上,則返回true
console.log(person1 instanceof Person) // true
console.log(person1 instanceof Object) // true

總結(jié)

  • 每個(gè)函數(shù)都有一個(gè)prototype屬性,值是一個(gè)原型對(duì)象
  • 每個(gè)對(duì)象都有一個(gè)__proto__屬性(null除外),指向構(gòu)造函數(shù)的原型prototype
  • 構(gòu)造函數(shù)的原型對(duì)象的constructor指向構(gòu)造函數(shù)本身
  • 原型對(duì)象是由Object構(gòu)造函數(shù)實(shí)例化產(chǎn)生的,所以原型對(duì)象的__proto__指向Object的原型對(duì)象Object.prototype
  • Object構(gòu)造函數(shù)的原型對(duì)象為null
function Person() {}
var person = new Person()
console.log(person.__proto__ === Person.prototype) // true
console.log(Person === Person.prototype.constructor) // true
console.log(Object.prototype.__proto__ === null) // true
// 推導(dǎo)person.constructor等于person.__proto__.constructor等于Person.prototype.constructor
console.log(person.constructor === Person.prototype.constructor) // true

到此這篇關(guān)于JavaScript深入淺出__proto__和prototype的文章就介紹到這了,更多相關(guān)JS proto 和 prototype內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論