網站文檔設置index.php哈市今日頭條最新
JavaScript是一種基于原型的語言,它的每個對象都擁有一個原型對象。當試圖訪問一個對象的屬性時,不僅僅會在該對象上搜尋,還會搜尋該對象的原型,以及該對象的原型的原型。依次層層向上搜索,直到找到一個名字匹配的屬性或到達原型鏈的末尾。這些屬性和方法就定義在Object的構造函數上的prototype屬性上,并不是再實列對象的本身。
原型
函數可以有屬性,每個函數都有一個特殊的屬性prototype(原型)看下面的一個列子:
function doSomething(){console.log('do something');}console.log(doSomething.prototype)
運行結果是:
可以看到這個原型對象本身也有一個constructor屬性,它指向doSomething函數本身,這允許通過實例訪問到其構造函數。此外,這個原型對象還繼承自Object.prototype,這意味著它可以通過[[Prototype]]鏈訪問到Object.prototype上的所有屬性和方法,如hasOwnProperty, isPrototypeOf, toString等。
原型鏈
原型鏈是JavaScript中實現繼承的一種機制。在JavaScript中,每個對象都有一個指向另一個對象的內部鏈接,這個被鏈接的對象稱為原型(prototype),而這個鏈接則被稱為對象的[[Prototype]]
。當嘗試訪問一個對象的屬性時,如果該對象本身不存在此屬性,JavaScript引擎就會通過這個鏈接查找該屬性,直至找到該屬性或到達原型鏈的末端(即null
)為止。這一系列通過[[Prototype]]
鏈接起來的對象就構成了原型鏈。
下面的圖解更利于理解
原型鏈的工作原理:
-
屬性查找:當你嘗試訪問一個對象的屬性時,JavaScript首先會在該對象自身查找。如果找不到,它會沿著原型鏈向上查找,直到找到該屬性或者到達原型鏈的頂端(
null
)。 -
構造函數與原型:每個函數都有一個
prototype
屬性,這個屬性是一個對象,包含可以由所有實例共享的屬性和方法。當你使用構造函數創(chuàng)建對象時,新對象的[[Prototype]]
將指向構造函數的prototype
屬性。 -
繼承:子對象可以通過設置其
[[Prototype]]
為另一個對象來實現對父對象的繼承。這樣,子對象就可以訪問父對象的所有屬性和方法,除非這些屬性和方法被子對象自己覆蓋。
function Person() {this.name='people';}Person.prototype.say=function(){console.log(this.name+'hello world');}function Man(){this.sex='man';}// 設置Man的原型為PersonMan.prototype=new Person();// 修改Man的構造函數Man.prototype.constructor=Man;const man=new Man();console.log(man.name);console.log(man.sex);man.say();// 查看原型鏈//打印 man 對象的直接原型,即 Man.prototype(這是一個通過 Person 構造函數創(chuàng)建的實例)。console.log(man.__proto__);console.log(Man.prototype)//打印 Man.prototype 的原型,也就是 Person.prototype。console.log(man.__proto__.__proto__);console.log(Person.prototype);//打印 Person.prototype 的原型,也就是 Object.prototype。console.log(man.__proto__.__proto__.__proto__);console.log(Object.prototype);//打印 Object.prototype 的原型,為 null。console.log(man.__proto__.__proto__.__proto__.__proto__);
在上面的列子中Man的原型指向了Person實列,這意味著Man不僅可以訪問自己的屬性和方法還可以通過原型鏈來訪問Person的的屬性和方法。