原型对象
所有的javascript方法都是一个对象----称为函数对象
函数对象有个自带属性prototype,这个属性就是原型对象(普通对象没有prototype)
原型对象用来做什么-----继承
var person = function(name){
this.name = name
};
person.prototype.getName = function(){
return this.name;
}
var hhc = new person('huahaichuan');
console.log(hhc.getName());
怎么实现的?往下继续原型链
原型链
- JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做
__proto__
的内置属性,用于指向创建它的函数对象的原型对象prototype ,这句话很费解
console.log(person.prototype)
console.log(hhc._proto_)
通过控制台发现hhc.__proto__==person.prototype
,再回过头去__proto__
指向创建它的函数对象的原型对象prototype
就不难理解了
同样,person.prototype
对象也有__proto__
属性,它指向创建它的函数对象(Object)的prototype
继续,Object.prototype
对象也有__proto__
属性,但它比较特殊,为null
我们把这个有__proto__
串起来的直到Object.prototype.__proto__
为null的链叫做原型链。
思考
var food = function(){}
food.price=5;
var fruit = function(){}
fruit.prototype=food;
var apple = new fruit();
console.log(fruit.price);
console.log(apple.price);
总结
原型和原型链是JS实现继承的一种模型。
原型链的形成是真正是靠
__proto__
而非prototype
补充和对比几种继承方式
- 原型链继承
var people = function(){
this.getName=function(){
return this.name;
}
}
var person = function(name){
this.name=name;
};
person.prototype = new people();
var hhc = new person('huahaichuan');
console.log(hhc.getName());
原型链方式继承缺点,就是实例化子类时不能将参数传给父类
- 临时属性方式
var people = function(age){
this.age=age;
this.getName=function(){
return this.name;
}
}
var person = function(name,age){
this.temp = people;
this.temp(age);
delete this.temp;
this.name=name;
};
var hhc = new person('huahaichuan',25);
console.log(hhc.getName());
console.log(hhc.age);
- call继承
var people = function(age){
this.age=age;
this.getName=function(){
return this.name;
}
}
var person = function(name,age){
this.name = name;
people.call(this,age);
};
var hhc = new person('huahaichuan',25);
console.log(hhc.getName());
console.log(hhc.age);
4.apply继承
var people = function(age){
this.age=age;
this.getName=function(){
return this.name;
}
}
var person = function(name,age){
this.name = name;
people.apply(this,[age]);
};
var hhc = new person('huahaichuan',25);
console.log(hhc.getName());
console.log(hhc.age);
call和apply的区别是传参形式不同
5.混合继承
var people = function(age){
this.age=age;
}
people.prototype.getName=function(){
return this.name;
}
var person = function(name,age){
this.name = name;
people.call(this,age); //成员变量采用对象冒充方式
};
person.prototype = new people(); //成员方法采用原型链方式
var hhc = new person('huahaichuan',25);
console.log(hhc.getName());
console.log(hhc.age);