如题
在典型的面向对象语言中,如Java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例。但是在js语言体系中,是不存在类的的概念的,js不是基于'类的',而是通过构造函数和原型链实现的。类的实现是基于原型机制的,如果两个实例都从同一个原型对象上继承了属性,我们称它们是同一个类的实例。也意味这它们很可能由同一个构造函数创建并初始化的 。
function Person(name,weight){
this.name = name;
this.weight = height;
this.hobby = function(){
return "basketball";
}
}
var pso1 = new Person("xiongda",180);
var pso2 = new Person("xionger",175);
console.log(pso1.hobby == pos2.hobby);//false
注意上面的hobby属性比较的输出false;
上面的方法产生了两个Person的实例,但是他们的hobby方法是不一样的。就是说在创建一个实例的时候,构造方法都会去创建一个hobby的方法。这样会很浪费资源。
所以构造函数的缺点:同一个构造函数的对象实例之间无法共享属性和方法。
为了解决这个问题,js提供了prototype属性。在js中,每个数据类型都是对象,(Null、Undefined 除外)而每个对象继承自另外一个对象,被继承的独享成为原型对象,只有null没有原型对象。原型对象的所有属性和方法都会被实例共享,这就类似Java的集成机制了。
现在来改善一下上面的这个例子。
function Person(name,weight){
this.name = name;
this.height = weight;
}
Person.prototype.hobby = function(){
return "basketball";
}
var pso1 = new Person("xiongda",180);
var pso2 = new Person("xionger",175);
console.log(pso1.hobby == pos2.hobby);//true
需要理解的是,对于构造函数来说,prototype是一个属性。对于对象的实例来说,prototype是对象实例的原型对象。所以prototype是实例也是对象。
a:原型对象的作用,就是定义所有对象实例所共享的属性和方法。
b:prototype,对于构造函数来说,它是一个属性;对于对象实例来说,它是一个原型对象。
原型链:
对象的属性和方法可以定义在自己的构造函数中,也可以定义为原型对象。由于原型对象本身对于对象实例来说也是对象,那么原型对象也可以拥有自己的原型,比如A的原型是B,B的原型是C,这样就形成了一个原型链,所有对象的最终原型对象都是Object,Object也拥有自己的原型对象null,null不拥有任何属性和方法。
特点:
a:在查找某个属性和方法时,会从实例本身顺着原型链开始查找
b:本身和原型都定义了同一个属性时,优先读取本身属性
c:某个属性越处于原型链的顶端,对性能消耗越大,甚至遍历整个原型链。