本節(jié)主要介紹對象的屬性類型以及創(chuàng)建對象的幾種方法荚斯。
對象的屬性類型:
ES中只有兩種屬性:數(shù)據(jù)屬性和訪問器屬性。
數(shù)據(jù)屬性
[[Configurable]]
: 是否可配置绍哎,如能否delete刪除屬性湖雹,能否修改為訪問器屬性等勤庐。
[[Enumerable]]
: 能否通過for-in返回屬性嗜桌。內(nèi)置對象自帶的原型屬性是不可枚舉的奥溺。
[[Writable]]
: 能否修改屬性值辞色。
[[Value]]
: 屬性的數(shù)據(jù)值骨宠。
訪問器屬性
[[Configurable]]
:能否修改屬性特征,能否delete刪除屬性相满,能否修改為訪問器屬性层亿。
[[Enumerable]]
: 能否通過for-in返回屬性。
[[Set]]
: 寫入屬性時調(diào)用立美。
[[Get]]
: 讀取屬性時調(diào)用匿又。
訪問器屬性必須使用Object.defineProperty()
定義。
var person = {
name: 'John',
surname: 'Smith',
}
Object.defineProperty(person, "fullname",{
get: function(){
return this.name + ' ' + this.surname
},
set: function(value){
this.name = value.split(' ')[0]
this.surname = value.split(' ')[1]
}
})
console.log(person.fullname)//'John Smith'
person.surname = 'Brown'
console.log(person.fullname)//'John Brown'
person.fullname = 'Ami Smith'
console.log(person.name)//'Ami'
創(chuàng)建對象的幾種方法對比:
1.對象字面量
var person1 = {
name: '小強(qiáng)',
age: 29,
sayName: function () {
console.log(this.name)
}
}
var person2 = {
name: '小紅',
age: 10,
sayName: function () {
console.log(this.name)
}
}
上面通過對象字面量的方式創(chuàng)建了兩個對象建蹄,person1和person2碌更。這種方法創(chuàng)建對象會產(chǎn)生大量的重復(fù)代碼。
2.工廠模式
function createPerson (name, age) {
var o = new Object()
o.name = name
o.age = age
o.sayName = function () {
console.log(this.name)
}
return o
}
var person1 = createPerson('小強(qiáng)', 10)
var person2 = createPerson('小紅', 10)
工廠模式?jīng)]有創(chuàng)建特定的對象類型洞慎,無法進(jìn)行對象的識別痛单。
3.構(gòu)造函數(shù)模式
function Person (name, age) {
this.name = name
this.age = age
this.sayName = function () {
console.log(this.name)
}
}
var person1 = new Person('小強(qiáng)', 10)
var person2 = new Person('小紅', 10)
- 構(gòu)造函數(shù)的方法與上述工廠模式相比,有以下區(qū)別:
1.沒有顯示的創(chuàng)建對象劲腿;
2.函數(shù)內(nèi)部使用this,將屬性和方法都寫到this上旭绒。
3.沒有return返回值
- 構(gòu)造函數(shù)的方法有個new Person()的過程,new的時候發(fā)生了什么焦人?
1.創(chuàng)建一個新的對象挥吵;
2.把構(gòu)造函數(shù)的作用域賦給這個新對象,這樣this就指向了這個對象花椭;
3.執(zhí)行構(gòu)造函數(shù)的代碼忽匈,將屬性和方法添加到新對象上;
4.返回這個新對象矿辽。
-
如何判斷對象類型脉幢?
通過constructor屬性判斷,該屬性指向構(gòu)造函數(shù)嗦锐。
image.png 構(gòu)造函數(shù)的缺點(diǎn):
構(gòu)造函數(shù)上的方法在每個實(shí)例上都是不同的方法嫌松,都需要重新創(chuàng)建一遍。
console.log(person1.sayName===person2.sayName) //false
4. 原型模式
每個函數(shù)都有一個原型屬性(prototype)奕污,這個屬性是一個指針萎羔,指向一個對象,該對象包含所有實(shí)例對象可以共享的屬性和方法碳默。
function Person(name, age){
this.name = name
this.age = age
}
Person.prototype.sayName = function(){
console.log(this.name)
}
Person.prototype.smart = true
var person1 = new Person('小強(qiáng)',10)
var person2 = new Person('小紅',10)
- 如何判斷對象的屬性是在原型對象上還是實(shí)例對象上定義的贾陷?
利用in可以判斷是否可以訪問到該屬性缘眶;
利用hasOwnProperty可以判斷實(shí)例中是否存在該屬性;
兩者結(jié)合可以判斷該屬性是否只存在于原型中髓废。
var person1 = new Person('小強(qiáng)',10)
var person2 = new Person('小紅',10)
person1.smart=false
//是否能訪問到該屬性
console.log("smart" in person1)//true
console.log("smart" in person2)//true
//實(shí)例中是否存在該屬性
console.log(person1.hasOwnProperty("smart"))//true
console.log(person2.hasOwnProperty("smart"))//false
//屬性是否只存在于原型中
console.log(("smart" in person1)&& !(person1.hasOwnProperty("smart")))//false
console.log(("smart" in person1) && !(person2.hasOwnProperty("smart")))//true
- 原型的利用:添加一個所有實(shí)例可訪問的共享屬性巷懈。
var time=new Date()
Date.prototype.format=function(){
return (this.getMonth() + 1) + '-'+this.getDate()
}
var formatTime = time.format()