每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象。
function Person(){
Person.prototype.name = "Pinocchio";
Person.prototype.age = 14;
Person.prototype.getName = function(){console.log(this.name);}
}
var person1 = new Person();
var person2 = new Person();
alert(person1.getName == person2.getName); //true
优点:方法不会被重新创建 。 缺点:所有属性和方法都共享,无法初始化参数。比如原型中有一个引用类型,那么一个实例属性的改变会导致另一个实例属性也发生改变。
6.2.4.1 理解原型对象
创建一个新函数时,就会以特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。
默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。
注意:在找原型对象时,构造函数用的是prototype,对象实例用的是__proto__
当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。
如果实例的原型里也没有找到。由于实例的原型也是对象,因此原型对象也有自己的原型对象。
当获取 person.constructor 时,其实 person 中并没有 constructor 属性,当不能读取到constructor 属性时,会从 person 的原型也就是 Person.prototype 中读取,正好原型中有该属性,所以:
person.constructor === Person.prototype.constructor
Object.getPrototypeOf()
可以方便得取得一个对象的原型。
alert(Object.getPrototypeOf(person1) == Person.prototype); //true
在实例中添加一个原型中有的属性或将其设为null,会屏蔽原型对象中保存的同名属性,且不会修改原型里的属性。除非用delete删除实例中的属性才可以继续访问原型中的属性。
-
person1.hasOwnProperty('name')
如果实例中有该属性,则返回true,不会考虑原型中是否有。 -
"name" in person1
in操作符可以单独使用也可在for-in中使用。in会在通过对象能访问到给定属性时返回true,无论在实例还是原型里。 -
Object.keys(obj)
会返回一个包含所有可枚举属性的字符串数组,不包含原型。 -
Object.getOwnPropertyNames()
会返回所有实例属性,不管是否可枚举的字符串数组。