js 面向对象 继承机制
根据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 面向对象 继承机制的更多相关文章
- js面向对象继承
前言 最近看到js面向对象这章节了,主要学习了原型和面向对象继承关系,为了梳理自己的知识逻辑,特此记录. js的面向对象 先说说我目前了解的js创建对象方法 1.写一个函数,然后通过new创建对象 2 ...
- 27、理解js的继承机制(转载自阮一峰)
Javascript继承机制的设计思想 作者: 阮一峰 日期: 2011年6月 5日 我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类&qu ...
- js面向对象 继承
1.类的声明 2.生成实例 3.如何实现继承 4.继承的几种方式 1.类的声明有哪些方式 <script type="text/javascript"> //类的声明 ...
- 关于JS面向对象继承问题
1.原型继承(是JS中很常用的一种继承方式) 子类children想要继承父类father中的所有的属性和方法(私有+公有),只需要让children.prototype=new father;即可. ...
- js 面向对象 继承
继承方式有四种: 1.call 2.apply 3.prototype 4.for in call 和 apply 的主要区别: call 传参数只能一个一个的传, apply 因为是用数组,所以可以 ...
- JS 面向对象 ~ 继承的7种方式
前言: 继承 是 OO 语言中的一个最为人津津乐道的概念.许多 OO 语言都支持两种继承方式:接口继承 和 实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.如前所述,由于函数没有签名,在 ...
- Javascript继承机制总结 [转]
转自:http://bbs.csdn.net/topics/260051906 Javascript继承 一直想对Javascript再次做一些总结,正好最近自己写了一个小型Js UI库,总结了一下J ...
- js面向对象之继承那点事儿根本就不是事
继承 说道这个继承,了解object-oriented的朋友都知道,大多oo语言都有两种,一种是接口继承(只继承方法签名):一种是实现继承(继承实际的方法) 奈何js中没有签名,因而只有实现继承,而且 ...
- js面向对象设计之class继承
EcmaScript 2015 (又称ES6)通过一些新的关键字,使类成为了JS中一个新的一等公民.但是目前为止,这些关于类的新关键字仅仅是建立在旧的原型系统上的语法糖,所以它们并没有带来任何的新特性 ...
随机推荐
- conductor Kitchensink示例
一个示例的厨房工作流程,演示了所有模式构造的使用. 定义 { "name": "kitchensink", "description": & ...
- Linux下php5.3.3安装mcrypt扩展
具体操作: 一.下载软件包 1.下载php(版本要与系统安装的一致) http://pan.baidu.com/s/1mifTbfE 2.下载libmcrypt(安装mcrypt需要此软件包) htt ...
- Nexus 使用配置
Nexus使用的一些基本设置 1.更改中央仓库地址为私服地址 既然我们配置了私服,那么相应的,我们的项目就应该使用Nexus的地址(Public Repository)来下载jar包 1.1.基于PO ...
- dfs小练 【dfs】
1.前n个自然数的所有排列: #include <iostream> #include <cstdio> #include <cstring> using name ...
- X_PU
通俗易懂告诉你CPU/GPU/TPU/NPU...XPU都是些什么鬼?[附把妹秘籍] 2017-10-27 19:54移动芯片/谷歌 作者:iot101君 物联网智库 原创 转载请注明来源和出处 现在 ...
- 各种语言使用HTTP Request
1. JAVA String requestContent = "{"id":"1","sort":"des" ...
- 排序矩阵中的从小到大第k个数 · Kth Smallest Number In Sorted Matrix
[抄题]: 在一个排序矩阵中找从小到大的第 k 个整数. 排序矩阵的定义为:每一行递增,每一列也递增. [思维问题]: 不知道应该怎么加,因为不是一维单调的. [一句话思路]: 周围两个数给x或y挪一 ...
- 删除排序数组中的重复数字 II · Remove Duplicates from Sorted Array II
重复一次 [抄题]: 给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度. 不要使用额外的数组空间,必须在原地没有额外空间的条件下完成. [思维问题]: [ ...
- 3-QT程序运行时报错E:\SogouInput\6.7.0.0329\程序异常终止,该怎么解决?
https://bbs.csdn.net/topics/390653779 出现这个错误的原因,使用声明的对象时,没有使用new对对象进行实例化. 包括:数组.
- Linux xxd命令
一.简介 xxd 命令用于使用二进制或十六进制格式显示文件内容,可以将指定文件或标准输入以十六进制转储,也可以把十六进制转储转换成原来的二进制形式. 二.选项 http://www.cnblogs.c ...