原型鏈原型的修改或改變
object的原型物件給我們提供的方法
建構函式就是為了建立出很多具有相同屬性和方法的例項物件
function
person
(name)};
// 使用建構函式建立例項化物件
var p1 =
newperson
('張三');
var p2 =
newperson
('李四'
);
每乙個例項物件都有sayname方法。但是這樣每次建立乙個物件都會產生乙個一樣的sayname方法,這很占用空間,而且也不符合**書寫規範(減少重複性)。
當我們這樣寫時
// 建立建構函式
function
person
(name)};
person.prototype.
sayname
=function()
// 使用建構函式建立例項化物件
var p1 =
newperson
('張三');
var p2 =
newperson
('李四');
p1.sayname()
;
發現p1.sayname()依然能夠執行。
檢測p1中是否有sayname這個屬性
console.
log(p1.
hasownproperty
('sayname'))
;// false
返回為false,說明p1中確實沒有sayname屬性。
這是因為p1作為建構函式person的例項化物件,它繼承了來自person的prototype屬性裡面的方法。
這裡就要看一下例項物件的__proto__屬性,
先列印一下
兩個屬性一摸一樣。
再進行一下對比
console.
log(person.prototype === p1.__proto__)
;
結果是true。
說明兩個屬性是完全相等的。
**使用object.getprototypeof()獲取物件的原型物件
就是person的prototype屬性。
這個物件裡sayname是我們自己新增的,constructor建構函式的意思,裡面的建構函式指向自身,__proto__這個屬性指向另乙個原型物件。
總結:
當呼叫某種方法或者查詢某種屬性時,首先會先在自身查詢,如果自身沒有這個屬性或者方法,就會去物件的__proto__屬性中去查詢,也就是建構函式的prototype中呼叫查詢。
任何物件都有原型物件,也就是prototype屬性,任何原型物件也是乙個物件,該物件就有__proto__屬性,這樣一層一層往上找,就形成了一條鏈,我們稱此為原型鏈;
每乙個例項物件都有乙個__proto__屬性,指向的建構函式的原型物件,建構函式的原型物件也是乙個物件,也有__proto__屬性,這樣一層一層往上找就形成了原型鏈。
可以通過給建構函式的prototype屬性新增屬性和方法來讓建立的例項物件繼承。
1、普通的暴力方法
person.prototype =
直接用乙個新的物件替換掉原來的原型物件,但是這樣不建議使用,因為原型物件中還儲存這其他的資訊,這樣就會將其他的屬性給抹除掉了。
2、使用 . 新增屬性和方法
person.prototype.
sayname
=function()
這種新增方式可以使用,但是還是不夠完美,因為這樣新增上去的屬性是可以被例項物件使用for in遍歷時遍歷到的,正常的屬於繼承的屬性是不應該被子元素遍歷到的。
3、使用object.defineproperty()方法,可以新增屬性時,定義屬性內部的特性。
object.
defineproperty
(person.prototype,
'sayname',}
)//定義多個
object.
defineproperties
(person.prototype,
, fullnmae:}}
)
這樣新增的屬性就不會被遍歷出來。
4、object.create()方法建立乙個新物件,使用現有的物件來提供新建立的物件的__proto__。
語法:object.create(proto, [propertiesobject])
proto:新建立物件的原型物件。
propertiesobject:可選。若沒有指定為 undefined,則是要新增到新建立物件的可列舉屬性(即其自身定義的屬性,而不是其原型鏈上的列舉屬性)物件的屬性描述符以及相應的屬性名稱。這些屬性對應object.defineproperties()的第二個引數
返回值:乙個新物件,帶著指定的原型物件和屬性。
例外:如果propertiesobject引數不是 null 或乙個物件,則丟擲乙個 typeerror 異常。
var p2 = object.
create
(p1,})
;
還可以利用這個建立乙個空的物件。
var obj3 = object.
create()
;
建立的空物件的原型也是乙個空物件。
1.hasownproperty() 方法會返回乙個布林值,指示物件自身屬性中是否具有指定的屬性
console.
log(p1.
getownproper
('mname'))
;// true
與他相似的還有in操作符,但是in會算上原型鏈中可以訪問的屬性
2.propertyisenumerable() 方法返回乙個布林值,表示指定的屬性是否可列舉。
console.
log(p1.
propertyisenumerable
('mname'))
;//true
3、 isprototypeof() 方法用於在person的原型鏈上搜尋是否有object原型
console.
log(person.prototype.
isprototypeof
(p1));
//true
4、 tostring:把物件用字串的形式表示出來
console.
log(p1.
tostring()
);//[object object]
5、 valueof() 方法返回指定物件的原始值。一般只有js內建的物件才會有原始值。沒有原始值的物件會返回自身。
console.
log(p1.
valueof()
);// 自身
JS原型物件,原型鏈
js中建立物件都是通過建構函式建立的,所以每個物件中都有乙個指向其建構函式的指標constructor var obj new object var arr new array var obj2 字面量建立實質上是上面方式的簡寫 var arr2 var str new string test 建立...
物件 原型與原型鏈
object.definepropertylet obj object.defineproperty obj,key1 console.log object.getownpropertydescriptor obj,key0 console.log object.getownpropertydesc...
JS原型(一) 原型物件
在了解js原型物件之前,我們需要了解一些基礎知識 首先是建構函式,我們要知道建構函式的幾個特點 建構函式的首字母必須大寫 區分於其他普通函式 內部使用的this物件,指向即將要生成的例項物件。使用new來生成例項物件 由此我們可以得到,任何函式只要通過new操作符來呼叫,那這個函式就可以稱為建構函式...