每个函数都有一个原型prototype属性,指向原型对象。使用原型对象的好处就是让所有实例共享原型对象所包含的属性和方法。
function Person(name, age){ this.name = name; this.age = age; } var p1 = new Person("tom",12);Person的prototype属性指向Person原型对象,原型对象中存放着constructor、类属性和方法。constructor指向Person
Person.prototype.isPrototypeOf(p1);//true Object.getPrototypeOf(p1) == Person.prototype; //true Person.prototype.constructor == Person; //true p1.constructor == Person; //true实例可以访问原型对象的属性和方法,但却不能复写,在实例上定义的同名属性或方法会阻断原型链的查找,因为对属性和方法的访问过程就是沿着原型链的查找过程,首先在实例上查找,找不到就到原型上查找。
function Person(){ } Person.prototype.name = "tom"; Person.prototype.age = 12; var p1 = new Person(); p1.name = "jerry"; p1.name; //jerry--》来自实例 var p2 = new Person(); p2.name; //tom--》来自原型delete删除的是实例上的属性或者方法
//接上面的代码 delete p1.name; p1.name; //tom Person.prototype.sayHi = function(){ console.log("hi"); } p1.sayHi = function(){ console.log("hello"); } p1.sayHi(); //hello delete p1.sayHi; p1.sayHi(); //hi检测一个属性或者方法存在于原型还是实例中,实例中返回true。
function Person(){ } Person.prototype.name = "tom"; Person.prototype.age = 12; var p1 = new Person(); p1.name = "jerry"; p1.hasOwnProperty("name");//true var p2 = new Person(); p2.hasOwnProperty("name");//false不论在不在实例上,只要能找得到,in就返回true
//接上面的代码 "name" in p1; //true "name" in p2;//trueObject.keys返回可枚举类型的属性名。Object.getOwnPropertyNames()返回值与枚举可否无关。
Object.getOwnPropertyNames(Person.prototype);//["constructor","name", "age"] Object.keys(Person.prototype);//["name","age"]下面方式的原型赋值,会改变原型的constructor指向,但是也可以通过例子2强行指定constructor,只不过此时的constructor变成了可枚举类型。通过Object.defineProperty可以改变constructor的枚举类型
function Person(){ } Person.prototype.name = "tom"; Person.prototype.age = 12; Person.prototype.constructor;//Person Person.prototype = { name:"tom1", age:13 } Person.prototype.constructor; //不再是Person,变为Object //例子2 Person.prototype = { onstructor:Person, ame:"tom1", age:13 }; Person.prototype.constructor;//Person Object.keys(Person.prototype);//["constructor","name", "age"]看下面的代码
function Person(){} var p1 = new Person(); Person.prototype = { name:"tom1", age:13 } p1.name; //undefinedp1的[[prototype]]还是指向只包含constructor的Person原型对象,后面Person.prototype指向了Object原型对象,p1的指向不变。