JavaScript原型與原型鏈深入探究使用方法
原型(prototype)
每一個函數(shù)都有一個 prototype 屬性,它默認(rèn)指向一個Object空對象(即稱為:原型對象)。
<script>
console.log(Date.prototype, typeof Date.prototype);
function fun(){
}
fun.prototype.test = function(){ //給原型對象添加一個方法
console.log('test()');
}
console.log(fun.prototype); // 默認(rèn)指向一個Object空對象(沒有我們的屬性)
</script>
原型對象中有一個屬性 constructor ,它指向函數(shù)對象。
<script>
function fun(){
}
console.log(Date.prototype.constructor === Date);
console.log(fun.prototype.constructor === fun);
</script>
給原型對象添加屬性(一般是方法) ===> 實(shí)例對象可以訪問。
有的時候我們想要在所有已經(jīng)存在的對象添加新的屬性或方法。
另外,有時候我們想要在對象的構(gòu)造函數(shù)中添加屬性或方法。
使用 prototype 屬性就可以給對象的構(gòu)造函數(shù)添加新的屬性:
<script>
function fun(){
}
fun.prototype.test = function(){//給原型對象添加方法(屬性)
console.log('test()');
}
var fn = new fun()//函數(shù)的所有實(shí)例對象自動擁有原型中的方法(屬性)
fn.test()
</script>
顯示原型與隱式原型
每一個函數(shù) function 都有一個 prototype,即顯示原型。默認(rèn)指向一個空的 Object 對象。
<script>
function fun(){
}
console.log(fun.prototype);
</script>
每個實(shí)例對象都有一個 __proto__ ,可稱為隱式原型。
<script>
function fun(){
}
var fn = new fun()
console.log(fn.__proto__);
</script>
對象的隱式原型的值 為其對應(yīng) 構(gòu)造函數(shù)的顯示原型的值。
<script>
function fun(){
}
// console.log(fun.prototype);
var fn = new fun()
// console.log(fn.__proto__);
console.log(fun.prototype === fn.__proto__); //結(jié)果是 true
</script>總結(jié):
函數(shù)的 prototype 屬性:在定義函數(shù)時自動添加的,默認(rèn)值是一個空的 Object 對象。
對象的 __proto__ 屬性:創(chuàng)建對象時自動添加的,默認(rèn)值為構(gòu)造函數(shù)的 prototype 屬性值。
程序員能直接操作顯示原型,但不能直接操作隱式原型(ES6之前)。
原型鏈
原型鏈(本質(zhì)為:隱式原型鏈,作用:查找對象的屬性或方法),訪問一個對象的屬性時,先在自身屬性中查找,找到返回;如果沒有,再沿著 __proto__ 這條鏈向上查找,找到返回;如果最終沒找到,返回 undefined。
<script>
console.log(Object.prototype.__proto__);
function Fun(){
this.test1 = function(){
console.log('test1()');
}
}
console.log(Fun.prototype);
Fun.prototype.test2 = function(){
console.log('test2()');
}
var fun = new Fun()
fun.test1()
fun.test2()
console.log(fun.toString())
fun.test3()
</script>

總結(jié):
JavaScript 對象有一個指向一個原型對象的鏈。當(dāng)試圖訪問一個對象的屬性時,它不僅僅在該對象上搜尋,還會搜尋該對象的原型,以及該對象的原型的原型,依次層層向上搜索,直到找到一個名字匹配的屬性或到達(dá)原型鏈的末尾。
<script>
function Fun(){
}
//函數(shù)的顯示原型指向的對象默認(rèn)是空 Object 實(shí)例對象(但 Object 不滿足)
console.log(Fun.prototype instanceof Object);
console.log(Object.prototype instanceof Object);
console.log(Function.prototype instanceof Object);
//所有函數(shù)都是 Function 的實(shí)例(包括 Function)
console.log(Function.__proto__ === Function.prototype);
// Object 的原型對象是原型鏈的盡頭
console.log(Object.prototype.__proto__);
</script>
原型鏈屬性問題
讀取對象的屬性值時:會自動查找到原型鏈中查找;設(shè)置對象屬性時:不會查找原型鏈,如果當(dāng)前對象中沒有此屬性,直接添加此屬性值并設(shè)置其值;方法一般定義在原型中,屬性一般通過構(gòu)造函數(shù)定義在對象本身上。
<script>
function Fun(){
}
Fun.prototype.a = 'xxx'
var fun = new Fun()
console.log(fun.a,fun);
var fun1 = new Fun()
fun1.a = 'yyy'
console.log(fun.a,fun1.a,fun1);
function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.setName = function(name){
this.name = name
}
var p1 = new Person('Tom',12)
p1.setName('Bob')
console.log(p1);
var p2 = new Person('Jack',12)
p2.setName('andy')
console.log(p2);
console.log(p1.__proto__ === p2.__proto__);
</script>
原型鏈 instanceof 使用
表達(dá)式:A instanceof B ;如果B函數(shù)的顯示原型對象在A對象的原型鏈中,返回true,否則返回false;Function是通過new自己產(chǎn)生的實(shí)例。
<script>
function Fun(){}
var fn = new Fun()
console.log(fn instanceof Fun);
console.log(fn instanceof Object);
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);
</script>
練習(xí)
<script>
function A(){}
A.prototype.n = 1
var b = new A()
A.prototype = {
n:2,
m:3
}
var c = new A()
console.log(b.n, b.m, c.n, c.m);
</script>
其實(shí)現(xiàn)原理如下圖所示(圖有點(diǎn)草,湊合看吧哈哈)

<script>
function F(){}
Object.prototype.a = function(){
console.log('a()');
}
Function.prototype.b = function(){
console.log('b()');
}
var f = new F()
f.a()
F.a()
F.b()
console.log(f);
console.log(Object.prototype);
console.log(Function.prototype);
</script>
到此這篇關(guān)于JavaScript原型與原型鏈深入探究使用方法的文章就介紹到這了,更多相關(guān)JS原型與原型鏈內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript實(shí)現(xiàn)Table排序的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)Table排序的方法,涉及javascript針對表格對象的獲取與排序相關(guān)技巧,需要的朋友可以參考下2015-05-05
JS ES6中setTimeout函數(shù)的執(zhí)行上下文示例
這篇文章主要給大家介紹了關(guān)于JS ES6中setTimeout函數(shù)的執(zhí)行上下文的相關(guān)資料,文中給出了詳細(xì)的介紹和示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來一起看看吧。2017-04-04
通過JavaScript實(shí)現(xiàn)撲克牌游戲的示例代碼
這篇文章主要為大家詳細(xì)介紹了JavaScript如何通過面向?qū)ο髮?shí)現(xiàn)一個簡單的撲克牌游戲,文中的示例代碼代碼講解詳細(xì),感興趣的可以學(xué)習(xí)一下2022-07-07
總結(jié)JavaScript的正則與其他語言的不同之處
我接觸過不少語言,我很看重一門語言的正則表達(dá)式是否強(qiáng)大,還有正則與語法的結(jié)合是否緊密.在這一點(diǎn)上,JavaScript做的還不錯,至少有正則字面量.當(dāng)然,最強(qiáng)大的還是Perl.但最近發(fā)現(xiàn)JavaScript中的正則有幾個不同于其他語言的地方,下面一起來看下。2016-08-08

