JavaScript继承实现方法——温故知新
2016-06-02 15:40
543 查看
原型继承示例代码:
调用instance.getSuperValue()会经历三个搜索步骤:1)搜索实例;2)搜索SubType.prototype;3)搜索SuperType.prototype,最后一步才会找到该方法。在找不到属性或方法的情况下,搜索过程总是要一环一环地前行到原型链末端才会停下来。
注意:
(1)getSuperValue()方法仍然还在SuperType.prototype中,但property则位于SubType.prototype中。因为property是一个实例属性,而getSuperValue()则是一个原型方法。
(2)给原型添加方法的代码一定要放在替换原型的语句之后。
(3)在通过原型链实现继承是,不能使用对象字面量创建原型方法。因为这样会重写原型链。
示例如下:
(4)原型链存在的问题:
1)所有实例共享一个超类型构造函数的属性;
2)创建子类型的实例时,不能向超类型的构造函数中传递参数。
示例代码:
通过使用call()方法(或apply()方法),我们实际是在(未来将要)新创建的SubType实例的环境下调用了SuperType构造函数。这样一来,就会在新SubType对象上执行SuperType()函数中定义的所有对象的初始化代码。结果,SubType的每个实例就都会具有自己的colors属性的副本了。
(2)传递参数:
方法都在构造函数中定义,因此函数服用就无从谈起了。
So,借用构造函数的技术也很少单独使用。
组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为JavaScript中最常用的继承模式。
他也有一个缺陷:无论什么情况下,都会调用两次超类型构造函数,一次在创建子类型原型的时候,另一次是在子类型构造函数内部。
大家普遍认为寄生组合式继承是引用类型最理想的继承范式。
<script>
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
}
function SubType(){
this.subproperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
return this.subproperty;
}
var instance = new SubType();
alert(instance.getSuperValue());
</script>
调用instance.getSuperValue()会经历三个搜索步骤:1)搜索实例;2)搜索SubType.prototype;3)搜索SuperType.prototype,最后一步才会找到该方法。在找不到属性或方法的情况下,搜索过程总是要一环一环地前行到原型链末端才会停下来。
注意:
(1)getSuperValue()方法仍然还在SuperType.prototype中,但property则位于SubType.prototype中。因为property是一个实例属性,而getSuperValue()则是一个原型方法。
(2)给原型添加方法的代码一定要放在替换原型的语句之后。
(3)在通过原型链实现继承是,不能使用对象字面量创建原型方法。因为这样会重写原型链。
示例如下:
//继承了SuperType
SubType.prototype = new SuperType();
//使用字面量添加新方法,会导致上一行代码无效
SubType.prototype = {
getSubValue: function(){
return this.subproperty;
}
}
(4)原型链存在的问题:
1)所有实例共享一个超类型构造函数的属性;
2)创建子类型的实例时,不能向超类型的构造函数中传递参数。
So,原型继承很少单独使用!
1、借用构造函数
示例代码:function SuperType(){
this.colors = ["red", "blue", "green"];
}
function SubType(){
//继承了SuperType
SuperType.call(this);
}
var instance1 = new SubType();
instancel1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green"
通过使用call()方法(或apply()方法),我们实际是在(未来将要)新创建的SubType实例的环境下调用了SuperType构造函数。这样一来,就会在新SubType对象上执行SuperType()函数中定义的所有对象的初始化代码。结果,SubType的每个实例就都会具有自己的colors属性的副本了。
(2)传递参数:
function SuperType(name){
this.name = name;
}
function SubType(){
//继承了SuperType,同时还传递了参数
SuperType.call(this, "NBee");
//实例属性
this.age = 20;
}
var intance = new SubType();
alert(intance.name);
alert(intance.age);
存在的问题:
方法都在构造函数中定义,因此函数服用就无从谈起了。So,借用构造函数的技术也很少单独使用。
2、组合继承
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
}
function SubType(name, age){
//继承属性
SuperType.call(this, name);
this.age = age;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
}
var instance1 = new SubType("Nbee", 20);
instance1.colors.push("black");
alert(instance1.colors);
instance1.sayName();
instance1.sayAge();
var instance2 = new SubType("Greg", 21);
alert(instance2.colors);
instance2.sayName();
instance2.sayAge();
组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为JavaScript中最常用的继承模式。
他也有一个缺陷:无论什么情况下,都会调用两次超类型构造函数,一次在创建子类型原型的时候,另一次是在子类型构造函数内部。
所有就有了下面的寄生组合式继承
//寄生组合式继承
function inheritPrototype(subType, superType){
var prototype = Object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
function SuperType(name){
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function(){
alert(this.name);
}
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function(){
alert(this.age);
}
var p1 = new SubType('p1', 11);
p1.colors.push('black');
p1.sayAge();
p1.sayName();
alert(p1.colors);
var p2 = new SuperType('p2');
p2.sayName();
alert(p2.colors);
寄生组合继承的高效率体现在它只调用了一次SuperType构造函数,并且因此避免了SubType.prototype上面创建不必要的/多余的属性。
大家普遍认为寄生组合式继承是引用类型最理想的继承范式。
相关文章推荐
- JSP生成静态html网页
- 【JS设计模式】装饰者模式和组合模式两者很像,那么这二者之间又有什么区别呢?
- 在Javascript操作JSON对象,增加 删除 修改的简单实现
- JSP页面处理日期格式
- js 日期大小比较
- JSP入门详解
- javascript闭包
- js的format 方法
- JavaScript对象掺杂点原型
- javascript学院专业
- javaScript文档中常用的集合
- JavaScript学习笔记(1)
- js 操作cookie
- es5、6新添加的js方法
- jsp页面上的东西
- 浅谈JavaScript 标准对象
- js实现购物车
- 欧拉函数 cojs 2181. 打表
- JS篇——javascript中的this
- js获取URL地址栏中的参数