6.1 理解对象
1. 数据属性
包含 Configurable,Enumerable, Writable 和 Value,
分别代表 是否可操作, 是否可返回值for-in,是否可重写 和 具体值默认undefined
2. 访问器属性
包含 Configurable,Enumerable, Get 和 Set,
分别代表 是否可操作, 是否可返回值for-in,读取调用函数 和 写入调用函数
3.使用体现
1.Object.defineProperty() // 定义一个对象
2.Object.defineProperties() // 定义多个对象
3.Object.getOwnPropertyDescriptor() // 取得给定属性的描述符
6.2 创建对象
1. 工厂模式
function createPerson(name, age, job) {
var o = new Object();
o.name = name
o.sayName = funtion() {
alert(this.name);
}
return o;
}
var person1 = createPerson('Nicol',12, 'ali');
var person2 = createPerson('Greg',15, 'ten');
特点:解决了创建多个相似对象
缺点: 没有解决对象识别问题 => alert( person1 instanceof createPerson ) // false
2.构造函数模式
function Person(name, age, job) {
this.name = name;
this.sayName = function() {
alert(this.name)
}
}
var person1 = new Person('Nic', 29, 'soft');
var person2 = new Person('SI', 21, 'MI');
特点: 1.使用new; 2.P大写; 3.构造函数的作用域赋给新对象;4.解决了对象识别问题
(alert( person1 instanceof Person ) // true)
缺点: 1. 如果不用new,则this指向window; 2. 构造函数中的函数在每个实例上都需要重新创建,造成资源浪费。
3.原型模式
function Person() {}
Person.prototype.name = 'Nic';
Person.prototype.age = '23';
Person.prototype.sayName = function () { alert(this.name) };
var person1 = new Person();
var person2 = new Person();
console.log(person1.sayName()) //'Nic'
console.log(person2.sayName()) //'Nic'
console.log(person1.sayName() === person2.sayName()) // true
特点: 1.Person.prototype.constructor 指向Person; 2. person1 指向 Person.prototype; 3.person1实例上没有sayName方法,根据原型链向上找到Person.prototype中有;4.hasOwnProperty()可判断实例peroson1上的属性,不能判断prototype上的属性;5. ’in' 能访问到就行;
缺点: 1. 虽然解决了方法共享问题,但制造出引用类型数据也同时共享的问题 ( friends: ['Shely', 'Court'] )
4. 组合使用构造函数模式和原型模式
function Person (name, age, job) {
this.name = name;
this.friends = ['Shily', 'Court']
}
Person.prototype = {
constructor: Person;
sayName: function () { alert( this.name ) }
}
person1.friends.push('Van') // 'Shily', 'Court', 'Van'
person2.friends // 'Shily', 'Court'
特点: 1.实例属性是构造函数中定义,而由所有实例共享的属性constructor和方法则是在原型中定义 2.往一个实例属性中添加,不会影响另一个实例中该属性值
5. 动态原型模式
function Person(name, age, job) {
this.name = name
···
if ( typeof this.sayName != "function") {
Person.prototype.sayName = fucntion() { alert(this.name) }
}
}
特点: 看起来比上面的4 工整许多,写在一个方法里
6. 寄生构造函数模式
特点: 比工厂函数 多了一个new 来创建实例;
7. 稳妥构造函数模式
不说了。
总结
构造函数P、原型P.p和实例p的关系: 每个构造函数都有一个原型对象(P中有P.p),原型对象都包含一个指向构造函数的指针(P.p -> P,也就是P.p 中的 constructor: P),而实例都包含一个指向原型对象的内部指针(p -> P.p)
网友评论