了解 JS 原型
原型概念
当创建了一个函数时,就会根据一组特定的规则为该函数创建一个 prototype 属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor 的属性 这个属性指向一个prototype
属性所在函数的指针
看个例子
function Person(){} var friend = new Person();
当Person对象被创建后Person对象会有一个prototype属性,它指向了默认为Person创建一个原型对象 Person Prototype 这里边有个属性 constructor它保留了 对象Person的引用
如果继续为原型对象添加其它方法,其方法都会在 Person Prototype原型对象中
如果实例化了一个Person对象那他的实例同样也是会指向 Person的原型对象,从而最终对象的所有实例都可访问这个原型对象中的属性
原型对象共享
function Person(){} Person.prototype.getName =function(){return "zhang"} var person1 = new Person(); var person2 = new Person(); console.log(person1.getName()); //zhang console.log(person2.getName());//zhang
因为对象实例中的[prototype]属性是指向原型对象的,所以给原型对象添加的方法对所有实例共享
原型重写
function Person(){} Person.prototype.getName =function(){return "zhang"} //重写原型对象 Person.prototype ={ //constructor:Person, //注:如果没有修正引用 则默认会指向Object getName:function(){ return "Zhang" } }
某些情况下,想将原型对象中的方法定义在一个对象中时,可以直接重写原型对象。因为所有对象都是继承自Object对象,所以所果重写原型后没有将contructor的指向重新指回Person的话,其constructor属性就会默认指向Ojbect
如下例,也就是说重写后不进行重新指向,会切段对象与原型对象的关系
var friend = new Person.prototype.constructor(); console.log(friend.constructor == Object);//false
原型链
function SuperType(){} SuperType.prototype.getName= function(){ return "Zhang"; } function SubType(){} SubType.prototype = new SuperType(); var sub = new SubType(); console.log(sub.getName()); //Zhang 可以访问Super原型对象的方法 //constructor指向了SuperType console.log(SubType.prototype.constructor==SuperType) //true
原型中常用方法
getPrototypeof() //Object.getPropertyOf(obj)是ES5中用来得到obj对象的原型对象的标准方法 Object.getPrototypeOf(sub)==SubType.prototype //true
isprototypeOf //是用来判断要检查其原型链的对象是否存在于指定对象实例中,是则返回true,否则返回false
hasOwnprototype //是用来判断一个对象是否有你给出名称的属性或对象。不过需要注意的是,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员
hasPrototypeProperty //是否为原型对象的属性
__proto__ 就是prototype对象