根据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. struts2 自带的 token防止表单重复提交拦截器

    在struts2中,我们可以利用struts2自带的token拦截器轻松实现防止表单重复提交功能! 1. 在相应的action配置中增加:  <interceptor-ref name=&quo ...

  2. 如何在java中发起http和https请求

    一般调用外部接口会需要用到http和https请求. 一.发起http请求 1.写http请求方法 //处理http请求 requestUrl为请求地址 requestMethod请求方式,值为&qu ...

  3. Spring ThreadPoolTaskExecutor

    1. ThreadPoolTaskExecutor配置 1 <!-- spring thread pool executor --> 2 <bean id="taskExe ...

  4. oracle pl/sql程序

    简单的pl/sql程序 declare begin dbms_output.put_line('hello world'); end; 什么是PL/SQL? pl/sql(Procedure lang ...

  5. Linux CentOS6.6 NFS服务的配置与安装

    一.简介 NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS的客 ...

  6. apache配置防盗链

    1.确保apache已开启rewrite.   2.在.htaccess文件中添加如下: RewriteEngine On RewriteCond %{HTTP_REFERER} !^http://X ...

  7. SVN的标准目录结构:trunk、branches、tags

    原文链接:http://techlife.blog.51cto.com/212583/223704/ 我们在一些著名开源项目的版本库中,通常可以看到trunk, branches, tags等三个目录 ...

  8. 201621123008《Java程序设计》第七周学习总结

    1. 本周学习总结 1.1 思维导图:Java图形界面总结 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 监听,事件源,事件,注册. 1.2 任意编写事件处理 ...

  9. 2018软工项目UML设计(团队)

    团队信息 队名:火箭少男100 本次作业课上成员 短学号 名 本次作业博客链接 2507 俞辛(临时队长) https://www.cnblogs.com/multhree/p/9821080.htm ...

  10. AJAX初尝试——ACM/ICPC类比赛气球管理系统

    很早之前做过一个,白板没界面,20秒暴力刷新,数据库每个team一个n列的对应n个题目的标记项,只能对单个比赛暴力把全部user_id导入单独的气球表(也就是cid=1000用这个表的话,cid100 ...