本節(jié)主要介紹對(duì)象的屬性類型以及創(chuàng)建對(duì)象的幾種方法。
對(duì)象的屬性類型:
ES中只有兩種屬性:數(shù)據(jù)屬性和訪問器屬性。
數(shù)據(jù)屬性
[[Configurable]]: 是否可配置,如能否delete刪除屬性,能否修改為訪問器屬性等。
[[Enumerable]]: 能否通過for-in返回屬性。內(nèi)置對(duì)象自帶的原型屬性是不可枚舉的。
[[Writable]]: 能否修改屬性值。
[[Value]]: 屬性的數(shù)據(jù)值。
訪問器屬性
[[Configurable]]:能否修改屬性特征,能否delete刪除屬性,能否修改為訪問器屬性。
[[Enumerable]]: 能否通過for-in返回屬性。
[[Set]]: 寫入屬性時(shí)調(diào)用。
[[Get]]: 讀取屬性時(shí)調(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)建對(duì)象的幾種方法對(duì)比:
1.對(duì)象字面量
var person1 = {
name: '小強(qiáng)',
age: 29,
sayName: function () {
console.log(this.name)
}
}
var person2 = {
name: '小紅',
age: 10,
sayName: function () {
console.log(this.name)
}
}
上面通過對(duì)象字面量的方式創(chuàng)建了兩個(gè)對(duì)象,person1和person2。這種方法創(chuàng)建對(duì)象會(huì)產(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)建特定的對(duì)象類型,無法進(jìn)行對(duì)象的識(shí)別。
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)建對(duì)象;
2.函數(shù)內(nèi)部使用this,將屬性和方法都寫到this上。
3.沒有return返回值
- 構(gòu)造函數(shù)的方法有個(gè)new Person()的過程,new的時(shí)候發(fā)生了什么?
1.創(chuàng)建一個(gè)新的對(duì)象;
2.把構(gòu)造函數(shù)的作用域賦給這個(gè)新對(duì)象,這樣this就指向了這個(gè)對(duì)象;
3.執(zhí)行構(gòu)造函數(shù)的代碼,將屬性和方法添加到新對(duì)象上;
4.返回這個(gè)新對(duì)象。
-
如何判斷對(duì)象類型?
通過constructor屬性判斷,該屬性指向構(gòu)造函數(shù)。
image.png 構(gòu)造函數(shù)的缺點(diǎn):
構(gòu)造函數(shù)上的方法在每個(gè)實(shí)例上都是不同的方法,都需要重新創(chuàng)建一遍。
console.log(person1.sayName===person2.sayName) //false
4. 原型模式
每個(gè)函數(shù)都有一個(gè)原型屬性(prototype),這個(gè)屬性是一個(gè)指針,指向一個(gè)對(duì)象,該對(duì)象包含所有實(shí)例對(duì)象可以共享的屬性和方法。
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)


- 如何判斷對(duì)象的屬性是在原型對(duì)象上還是實(shí)例對(duì)象上定義的?
利用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
- 原型的利用:添加一個(gè)所有實(shí)例可訪問的共享屬性。
var time=new Date()
Date.prototype.format=function(){
return (this.getMonth() + 1) + '-'+this.getDate()
}
var formatTime = time.format()
創(chuàng)建對(duì)象的總結(jié)

