原型模式
什么是原型?
每个函数都有一个prototype(原型)属性,函数的prototype指向原型对象,(函数.prototype即为原型),原型 中的属性、方法在每个实例中共享。
例如:
function Person () { // 构造函数
}
Person.prototype.name = '张' // 此时name属性被添加到原型中
Person.prototype.sayName = function () {
console.log(this.name);
}
var person1 = new Person(); // 实例化构造函数(new 函数名)
var person2 = new Person(); // 实例化构造函数(new 函数名)
person1.sayName == person2.sayName // true 访问的都是同一函数
理解原型:
每个函数都有一个prototype属性指向该函数的原型对象,每个原型对象都有一个默认属性constructor 指向该原型对象的构造函数在上边例子中的表现为:
Person // 构造函数
Person.prototype // 表示原型对象
Person.prototype.constructor // 指向Person
通过isPrototypeOf()可以确定实例化对象的[[prototype]]是否指向构造函数的prototype
Person.prototype.isPrototypeOf(person1) // true
Person.prototype.isPrototypeOf(person2) // true
ECMAScript5中新增Object.getPrototypeOf()方法,获取的结果是实例对象的[[prototype]]值即构造函 数的prototype;
Object.getPrototypeOf(person1) == Person.prototype // true
Object.getPrototypeOf(person2) == Person.prototype // true
如果在实例中和原型中都有一个相同的属性,那么读取的时候将会只会读取实例中的属性,如果实例中没有 则会在原型中搜索
console.log(person1.name) // '张'
person1.name = '零零';
console.log(person1.name) // '零零'
在实例中修改属性将不会影响原型中的属性,
person1.name = '零零';
console.log(person1.name) // '零零'
console.log(person2.name) // '张' 此时的name值还是原型中的name属性值
通过hasOwnPrototype()可以判断是原型属性还是实例属性:
person1.name = '零零';
person1.hasOwnPrototype('name') // true 实例属性
person2.hasOwnPrototype('name') // false 原型属性
in的使用:
除了在for-in中使用外,in可以查找属性是否存在与对象中(实例或者原型中的属性只要存在则返回true)
person1.name = '实例'
console.log('name' in person1) // true 来自实例属性
console.log('name' in person2) // true 来自原型属性
for-in:枚举实例和原型中的所有可枚举的属性
实例中声明的属性将覆盖原型中的属性,此时枚举出来的属性是实例中的属性
Object.keys(对象):获得所有可枚举的实例属性 返回数组
function Person () { // 构造函数
}
Person.prototype.name = '张' // 此时name属性被添加到原型中
Person.prototype.sayName = function () {
console.log(this.name);
}
Object.keys(Person.prototype); // name,sayName
var person = new Person();
person.ss = 'ss';
Object.keys(person); // ss (不会获取原型中的枚举属性)