什么是prototype
我们创建的每个函数都有一个prototype属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。对普通函数来说这个属性没什么用,只有在构造函数创建实例的时候该属性有用。
prototype用处
举个例子:
var Student=function(n,a){
this.name=n;
this.age=a;
}
Student.prototype.show=function(){
console.log(this.name+this.age);
}
var s1=new Student('tom',15);
s1.show();
你创建了一个学生类,你发现这个学生类创建出的所有实例的show这个方法是完全一样的,如果你把show这个方法绑定到this上,那么每次创建实例的时候都会新建一个show方法出来,这是没有必要的,所以你把该类实例共享的这类属性给放在prototype对象中,所有实例是共用一个原型的。这样既保证了每个实例都有show这个方法,又不必每次创建实例的时候都新建这个方法。
在说原理之前你得懂这些知识点,每个实例对象都有一个__proto__指针,指向构造该实例的构造函数的prototype。因为任何一个对象,都可以充当其他对象的原型,所以实例对象也可以作为构造函数去创建自己的实例。然后当一个对象寻找某个属性的时候,他会先看自己有没有这个属性,如果没有就看自己的原型有没有这个属性,如果没有再去__proto__指向的构造函数的prototype里面看有没有,依次向上追溯,直至Object.prototype。因为所有对象都是Object对象的实例。这就是原型链。
所以上面的例子中,s1在调用show的时候,先在自己内部找show这个方法,没找到,就去自己的原型里面找,也没有,就沿着__proto__指针找到了Student.prototype,然后就找到了。
(注意IE浏览器不支持__proto__打印)
prototype原形对象中有一个属性叫做constructor构造属性,指向prototype对象所在的构造函数。作用是得知某个实例对象到底是哪个构造函数创建出来的。
接下来介绍一些运算符instanceof
使用方法:
var Student=function(n,a){
this.name=n;
this.age=a;
}
var s1=new Student('tom',15);
console.log(s1 instanceof Student);//true
console.log('str' instanceof String);//false
console.log(12 instanceof Number);//false
左边操作数为对象(如果不小心写成基本类型 比如数字啥的,就会返回false),右边操作数是函数构造器,否则抛出TypeError。 实质就是:instanceof操作符判断左操作数对象的原型链上是否有右边这个构造函数的prototype属性,也就是说指定对象是否是某个构造函数的实例,最后返回布尔值。
使用方法:
var Student=function(n,a){
this.name=n;
this.age=a;
}
Student.prototype.show=function(){};
var s1=new Student('tom',15);
console.log('name' in s1);//true
console.log('show' in s1);//true
左边是字符串形式的属性名,右边是对象。作用是判断右边对象是否含有该属性名。无论该属性在实例中还是,原型中。Object对象的方法
Object.prototype.isPrototypeOf()
举个例子:
var Student=function(n,a){
this.name=n;
this.age=a;
}
Student.prototype.show=function(){};
var s1=new Student('tom',15);
console.log(Student.prototype.isPrototypeOf(s1));//true
用以判断调用此方法的对象是否为,作为参数的对象的原型。
Object.prototype.hasOwnProperty()
借用上面那个例子:
console.log(s1.hasOwnProperty('name'));//true
console.log(s1.hasOwnProperty('show'));//false
这个方法用来判断该对象属性,是定义在对象自身,还是在原型链上。如果是在自身,返回true。