不妨從一個案例入手:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<div id="weizu">
</div>
<script>
function person(){}
var xm = new person();
var xg = new person();
xm.name = '小明';
xg.name = '小剛';
xg.age = 18;
console.log(xm);
console.log(xg);
</script>
</body>
</html>
我們可以每次都去創建某個實例對象的屬性,但是,這樣就導致了同一個person
對象給人的感覺就是怎麼一會兒又某個屬性,一會沒有該屬性,爲編程人員造成編程的不便。故而我們往往需要在類中
加入一些屬性,在JavaScript
中也就是原型中添加。添加如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<div id="weizu">
</div>
<script>
function person(){}
person.prototype.name = '張三';
person.prototype.age = 18;
var xm = new person();
var xg = new person();
console.log(xm.name, xm.age);
console.log(xg.name, xg.age);
</script>
</body>
</html>
上面可以看見,兩個實例對象調用的都是相同的內容。那麼有沒有可能是兩個實例對象引用的同一塊地址空間?回答這個問題之前,不妨先了解一下:
上圖原文地址:秒懂JavaScript的原型對象與原型鏈
也即是:函數對象有prototype
指向的對象是原型對象;普通對象有__proto__
屬性,它所指向的對象就是原型對象;
我們不妨來看看依據函數對象創建的實例對象的原型對象是不是同一個東西:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<script>
function Person(){}
Person.prototype.name = '張三';
var a = new Person();
a.name = "123";
var b = new Person();
b.name = '234';
console.log(a.name);
console.log(b.name)
console.log(a.__proto__ == Person.prototype);
console.log(a.__proto__ == b.__proto__);
</script>
</body>
</html>
原型對象是一樣的, 但是創建的對象是不同的。可以理解成指向的類函數是一樣的,new
後分配的空間是不同的。
故而一個函數對象創建的多個對象的原型對象是指向的同一個地址空間。
結合上個案例知道,我們創建的實例中沒有該屬性的時候,就會去原型中找該屬性。也就是順序是:先從對象中找,對象中沒有就去原型中找
。而會不會出現原型中沒有的情況?然後取原型的原型中去找?答案是肯定的,這也就是所謂的原型鏈的產生。
先了解下判斷是否有屬性的方法:
in
: 判斷對象是否有某個屬性,如果對象中沒有,就檢查原型中;hasOwnProperty()
: 檢查對象自身中是否有該屬性;
案例不太好舉,就不舉例了。
參考:
【1】 視頻-前端:JavaScript基礎+高級+jQuery教程
【2】秒懂JavaScript的原型對象與原型鏈