根据w3cschool上的描述:共有3种继承方法(对象冒充,原型链,混合)

1、对象冒充:构造函数ClassA使用this关键字给所有属性和方法赋值,使ClassA构造函数成为ClassB的方法,调用。可实现多重继承。

注意:所有新属性和新方法都必须在删除新方法的代码行后定义,否则会覆盖父类的相关属性和方法,多重继承时存在同名问题。

原始:

function ClassA(sColor){
this.color = sColor
this.sayColor = function(){
alert(this.color);
};
}; function ClassB(sColor, sName){
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod; //新属性和方法
this.name = sName;
this.sayName = function(){
alert(this.name);
}
} var objA = new ClassA('blue');
var objB = new ClassB('red', 'jack');

call():function对象的一个方法,它是ECMASript把对象冒充规范化的结果

function ClassB(sColor, sName) {
//this.newMethod = ClassA;
//this.newMethod(color);
//delete this.newMethod;
ClassA.call(this, sColor); this.name = sName;
this.sayName = function () {
alert(this.name);
};
}

apple():与call类似,第二个参数是数组或arguments(参数对象,两个类中的参数顺序完全一致的话,才可以)

function ClassB(sColor, sName) {
//this.newMethod = ClassA;
//this.newMethod(color);
//delete this.newMethod;
ClassA.apply(this, new Array(sColor)); this.name = sName;
this.sayName = function () {
alert(this.name);
};
}

以上存在内存浪费的问题。那就是对于每个实例对象而言,属性和方法都是一样的,但是每次创建新的实例,都要为其分配新的内存空间,这样做就会降低性能,浪费空间,缺乏效率。

2、原型链:把ClassB的prototype属性设置成ClassA的实例。ClassA的构造函数不能传递参数。

注意:所有新属性和新方法都必须在删除新方法的代码行后定义,否则会覆盖父类的相关属性和方法:因为prototype属性被替换成了新对象,添加了新方法和属性的原始对象将被销毁。

对 ClassB 的所有实例,instanceof 为 ClassA 和 ClassB 都返回 true。对象冒充时不能这样(instanceof是讲类型的,而对象冒充是讲方法的。)。不支持多重继承。

//确保构造函数没有任何参数
function ClassA(){ }
//方法用原型链
ClassA.prototype.color = 'blue';
ClassA.prototype.sayColor = function(){
alert(this.color);
} function ClassB(){ }
//把 ClassB 的 prototype 属性设置成 ClassA 的实例
ClassB.prototype = new ClassA(); //新方法和属性
ClassB.prototype.name = '';
ClassB.prototype.sayName = function(){
alert(this.name);
}

3、混合方式:对象冒充的缺点,每个子类都有与父类相同的方法,这样很占空间;而原型链,子类只是指向父类的方法。但是不能多重继承。所以需要结合起来:对象冒充继承属性;原型链继承方法。

通过对象冒充方式继承时,所有的成员方法都是指向this的,也就是说new之后,每个实例将都会拥有这个成员方法,并不是共用的,这就造成了大量的内存浪费。并且通过对象冒充的方式,无法继承通过prototype方式定义的变量和方法(与我想的一样)

//父类属性用构造函数
function ClassA(sColor) {
this.color = sColor;
}
//不变的用原型链
ClassA.prototype.sayColor = function () {
alert(this.color);
};
//子类构造函数用对象冒充继承
function ClassB(sColor, sName) {
ClassA.call(this, sColor);
this.name = sName;
}
//方法用原型链继承
ClassB.prototype = new ClassA();
//
ClassB.prototype.constructor = ClassB
//新方法写在最后
ClassB.prototype.sayName = function () {
alert(this.name);
};

注意:所谓的新属性,在对象冒充中是this.name。在原型链中是prototype.name。

instanceof深入学习

(1)值类型:数值、布尔值、null、undefined。

(2)引用类型:对象、数组、函数。

instanceof为了弥补typeof的不足,作用:实例是否属于某种类型;实例是否属于它的父类型;

新概念:显示原型,隐式原型:新概念,哈哈

真难:http://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/

http://www.alloyteam.com/2015/06/javascript-shu-ju-jie-gou-he-suan-fa-jian-shu-qian-yan/

继承有三种方式:

1、

之前提到的混合方式

2、YUI继承

function Animal() {}
Animal.prototype.feeling = 'happy'; function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
} extend(Dog, Animal); var dog = new Dog('二狗', '哈士奇');
print(dog.feeling); // happy

3、jquery继承

function Animal() {}
Animal.prototype.feeling = 'happy'; function deepCopy(Child, Parent) {
var p = Parent.prototype;
var c = Child.prototype;
for (var i in p) {
if (typeof p[i] === 'object') {
c[i] = (p[i].constructor === Array) ? [] : {};
deepCopy(p[i], c[i]);
} else {
c[i] = p[i];
}
}
} deepCopy(Dog, Animal); var dog = new Dog('二狗', '哈士奇');
print(dog.feeling); // happy

看情况用吧。

明白了

混合继承时,为什么要加:ClassB.prototype.constructor = ClassB

这篇教程写的很好,自己现在记录一下:http://www.jb51.net/article/22334.htm

重新覆盖prototype后,这条链上的对象和方法的constructor都变为object,为了纠正,需要把constructor重新定义。

对象继承 一般用混合方式比较好,w3cschool上的例子很清楚。 

YUI的更高效和简洁。 

js 面向对象 继承机制的更多相关文章

  1. js面向对象继承

    前言 最近看到js面向对象这章节了,主要学习了原型和面向对象继承关系,为了梳理自己的知识逻辑,特此记录. js的面向对象 先说说我目前了解的js创建对象方法 1.写一个函数,然后通过new创建对象 2 ...

  2. 27、理解js的继承机制(转载自阮一峰)

    Javascript继承机制的设计思想   作者: 阮一峰 日期: 2011年6月 5日 我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类&qu ...

  3. js面向对象 继承

    1.类的声明 2.生成实例 3.如何实现继承 4.继承的几种方式 1.类的声明有哪些方式 <script type="text/javascript"> //类的声明 ...

  4. 关于JS面向对象继承问题

    1.原型继承(是JS中很常用的一种继承方式) 子类children想要继承父类father中的所有的属性和方法(私有+公有),只需要让children.prototype=new father;即可. ...

  5. js 面向对象 继承

    继承方式有四种: 1.call 2.apply 3.prototype 4.for in call 和 apply 的主要区别: call 传参数只能一个一个的传, apply 因为是用数组,所以可以 ...

  6. JS 面向对象 ~ 继承的7种方式

    前言: 继承 是 OO 语言中的一个最为人津津乐道的概念.许多 OO 语言都支持两种继承方式:接口继承 和 实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.如前所述,由于函数没有签名,在 ...

  7. Javascript继承机制总结 [转]

    转自:http://bbs.csdn.net/topics/260051906 Javascript继承 一直想对Javascript再次做一些总结,正好最近自己写了一个小型Js UI库,总结了一下J ...

  8. js面向对象之继承那点事儿根本就不是事

    继承 说道这个继承,了解object-oriented的朋友都知道,大多oo语言都有两种,一种是接口继承(只继承方法签名):一种是实现继承(继承实际的方法) 奈何js中没有签名,因而只有实现继承,而且 ...

  9. js面向对象设计之class继承

    EcmaScript 2015 (又称ES6)通过一些新的关键字,使类成为了JS中一个新的一等公民.但是目前为止,这些关于类的新关键字仅仅是建立在旧的原型系统上的语法糖,所以它们并没有带来任何的新特性 ...

随机推荐

  1. 利用Spark-mllab进行聚类,分类,回归分析的代码实现(python)

    Spark作为一种开源集群计算环境,具有分布式的快速数据处理能力.而Spark中的Mllib定义了各种各样用于机器学习的数据结构以及算法.Python具有Spark的API.需要注意的是,Spark中 ...

  2. mysql 数值与字符类型 长度梳理

    上述表格中的数值类型都是定长的,也就是说,无论你存的数值是多少,多大或者多小,占用的存储字节大小都是固定的.例如,设置int(1),虽然M值是1个字符,但是它所占用的空间大小永远都是4个字节的大小,换 ...

  3. 元素的定位id和name

    1.元素定位: 元素的定位是自动化测试的核心,要想操作一个元素,首先应该识别这个元素 webdriver提供了一系列的元素定位方法,常用的有以下几种 id name class name partia ...

  4. 开始一个Android的appium实例

      1.查看Android的应用包名和activity的方法   (网上有很多种方法,这里应用的是查看日志的方法) CMD中输入>adb logcat -c                   ...

  5. Usage of “symmetrical” and “symmetric”

    What is the appropriate usage of "symmetrical" and "symmetric" (using the geomet ...

  6. cdoj203-Islands 【并查集】

    http://acm.uestc.edu.cn/#/problem/show/203 Islands Time Limit: 30000/10000MS (Java/Others)     Memor ...

  7. tf.random_normal()

    tf.random_normal()函数用于从服从指定正太分布的数值中取出指定个数的值. tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf. ...

  8. 判断Javascript对象是否为空

    判断普通javascript对象是否为空(含有可枚举的属性,自有的.继承的都可以),可使用jQuery 3.2.1版的isEmptyObject()方法: isEmptyObject: functio ...

  9. 复杂度分析 quick sort&merge sort

    空间复杂度看新开了什么数据结构就够了 公式=几个点*每个点执行了多少次 二叉树都是n次 二分法查找:lgn 全部查找:n n:找一个数,但是两边都要找.相当于遍历.类似于rotated sorted ...

  10. [leetcode]215. Kth Largest Element in an Array 数组中第k大的元素

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...