1. 原型对象:通过调用构造函数而创建的对象的实例都有一个原型对象,该原型对象包含同一个构造函数创建的对象所共享的属性和方法。
2. prototype属性:创建的每个函数都有一个prototype属性,该属性是一个指针,指向原型对象。
3. 使用原型对象的好处是:让所有的对象实例共享他所包含的属性和方法。
如: function Person(){
}
Person.prototype.name = "rourou";
Person.prototype.age = 22;
Person.prototype.sayName = function(){
console.log(this.name);
};
var p1 = new Person();
console.log(p1.name); //rourou
console.log(p1.sayName()==p2.sayName()); //true----因为p1和p2共享sayName函数
图例:
这里的 [[ prototype ]] 在所有的实现中都没办法访问。
4. isPrototypeOf(参数):判断实例对象和原型对象之间是否存在联系。
Object.getPrototypeOf(参数):返回的是 [[ prototype ]] 的值,即原型对象。
如:console.log(Person.prototype.isPrototypeOf(p1)); //true,证明p1实例对象和原型对象之间存在联系。
console.log(Object.getPrototypeOf(p1)); //{name: "rourou", age: 22, sayName: ƒ, constructor: ƒ}
console.log(Object.getPrototypeOf(p1).name); //rourou
5. 不能通过对象实例重写原型对象中的值,但可以通过对象实例访问原型对象中的值。(在读取某个对象中的属性时,首先会先搜索对象实例本身,如果没有再搜索原型对象)。通过delete删除属性或方法(原型对象和实例对象都可以删除)
function Person(){
}
Person.prototype.name = "rourou";
Person.prototype.age = 22;
Person.prototype.sayName = function(){
console.log(this.name);
};
var p1 = new Person();
var p2 = new Person();
p1.name = "baobao";
console.log(p1.name); //baobao
console.log(p2.name); //rourou----可以看出,通过对象的实例不能重写属性,只能覆盖属性(与访问顺序有关)
delete p1.name;
console.log(p1.name); //rourou
delete Person.prototype.name;
console.log(p2.name); //undefined
6. hasOwnProperty():判断一个属性是存在于实例中还是原型中。在实例中返回true
in操作符:在可以访问给定属性时,返回true。(无论该属性是在实例中还是原型中)
如:① hasOwnProperty()
function Person(){
}
Person.prototype.name = "rourou";
Person.prototype.age = 22;
Person.prototype.sayName = function(){
console.log(this.name);
};
var p1 = new Person();
var p2 = new Person();
p1.name = "baobao";
console.log(p1.hasOwnProperty("name")); //true
console.log(p1.hasOwnProperty("age")); //false
console.log("age" in p1); //true
图例:
7. 更简单的原型语法:
这里将Person.prototype的所有实例属性封装在一起。(相当于重写)但是缺点是原型属性的constructor指向的是Object构造函数。
图例:
可以将constructor指向Person构造函数
8. 原型的动态性:如果不重写原型对象,那么先创建对象,再在原型对象中添加属性,还是先在原型对象中添加属性,在创建对象,都是可以访问到相应的属性和方法的。
但是,如果重写了原型对象,那么先创建还是后创建就有区别了。因为先创建对象再重写时,实例对象指向的是原来的原型对象。(会切断现有实例与新原型之间的联系)
图例:所以访问后来添加的属性,值为undedined