对象的属性
对象属性包括数据属性和访问器属性
1. 数据属性:包含下面4个特征
- [[Configurable]]: 表示能否通过delete删除属性从而重新定义,能否修改属性特性,默认 值为true。
- [[Enumerable]]: 能否通过for-in循环返回属性,默认true。
- [[Writable]]: 能否修改属性值,默认true。
- [[Value]]: 属性数据值,默认undefined。
var person = {};
Object.defineProperty(person, "name", {
configurable: false,
value: "Nicholas"
});
alert(person.name); //"Nicholas"
delete person.name;
alert(person.name); //"Nicholas"
2.访问器属性
访问器属性不包含数据值;包含getter(读取该属性)和setter(写入该属性传值);下面4个特性,其中也包括, [[Configurable]]、[[Enumerable]],以及[[Get]]、[[Set]]。
访问属性不能直接定义,需要通过Object.defineProperty()
来定义,例如:
var book = {
_year: 2016, //'_'用于表示只能通过对象方法访问的属性
edition: 1
};
Object.defineProperty(book, "year", {
get: function() { //在读取属性是调用的函数
return this._year;
},
set: function(newValue) { //在写入属性时调用的函数
if(newValue > 2016) {
this._year = newValue;
this.edition +=newValue-2016;
}
}
});
book.year = 2017;
alert(book.edition); //2
3.定义多个属性
通过Object.defineProperties
可定义多个属性。
支持该方法的浏览器有IE 9+、firefox 4+、Safari 5+、Opera 12+和Chrome。
var book = {};
Object.defineProperties(book, {
_year: {
value: 2016
},
edition: {
value:!
},
year: {
get: function() {
return this._year;
},
set: function(newValue) {
if (newValue > 2016) {
this._year = newValue;
this.edition += newValue - 2016;
}
}
}
});
var descriptor = Object.getOwnPropertyDescriptor()
4.读取属性的特性
用 Object.getOwnPropertyDescriptor()
方法判断属性是数据属性或访问属性。
支持该方法的浏览器有IE 9+、firefox 4+、Safari 5+、Opera 12+和Chrome。
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
alert(descriptor.value); //2017
alert(descriptor.writable); //true
var descriptor2 = Object.getOwnPropertyDescriptor(book, "year");
alert(descriptor2.value); //undefined
alert(descriptor2.writable); //undefined
创建对象
1、对象字面量或者Object构造函数。
var obj = new Object();
或
var obj = {
name: "name1",
age: 7
}
2、工厂模式
function createPerson(name, age, job) {
var o = new object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
}
return o;
}
var person1 = createPerson("Nicholas", 10, "job1");
var person2 = createPerson("Greg", 11, "job2");
3、构造函数模式
function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
alert(name);
}
}
var person1 = new Person("Nicholas", 10);
var person2 = new Person("Greg", 11);
4、原型模式
该方法原型内所有属性和方法都是共享的,这样会导致一些问题。如下所示,修改一个的friends另一个也修改了。
function Person() {
}
Person.prototype = {
constructor: Person,
name : "Nicholas",
age : 12,
friends: ["Shelby", "Court"],
sayName : function() {
alert(this.name);
}
}
var person1 = new Person();
var person2 = new Person();
person1.friends.push("van");
alert(person1.friends); //"Shelby,Court,van"
alert(person2.friends); //"Shelby,Court,van"
alert(person1.friends===person2.friends); //true
5、组合使用构造函数模式和原型模式
function Person(name, age) {
this.name = name;
this.age = age;
this.friends = ["Shelby", "Court"]
}
Person.prototype = {
constructor: Person,
sayName: function() {
alert(this.name);
}
}
var person1 = new Person("aaa", 2);
var person2 = new Person("bbb", 3);
person1.friends.push("van");
alert(person1.friends); //"Shelby,Court,van"
alert(person2.friends); //"Shelby,Court"
alert(person1.friends==person2.friends); //false
alert(person1.sayName==person2.sayName); //true
6、动态原型模式
function Person(name, age) {
this.name = name;
this.age = age;
this.friends = ["Shelby", "Court"];
if (typeof this.sayName != "function") { //只有在该方法不存在的时候才会添加到原型中,初次调用构造函数的时候执行。
Person.prototype.sayName = function() {
alert(this.name);
}
}
}
var friend = new Person("ss0", 12);
friend.sayName();
还有还有寄生构造函数模式和稳妥构造函数模式。