第一种:对象冒充

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", "John");
objA.sayColor();
objB.sayColor();
objB.sayName();

  注意:  所有新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法:  

第二种: 通过Function 对象上面的call, apply方法来实现继承。

function ClassA(sColor) {
this.color = sColor;
this.sayColor = function () {
alert(this.color);
};
} function ClassB(sColor, sName) {
//this.newMethod = ClassA;
//this.newMethod(color);
//delete this.newMethod;
ClassA.apply(this, arguments); this.name = sName;
this.sayName = function () {
alert(this.name);
};
} var objA = new ClassA("blue");
var objB = new ClassB("red", "John");
objA.sayColor();
objB.sayColor();
objB.sayName();

  第三种:原型链 prototype 属性对象。

function ClassA() {
} ClassA.prototype.color = "red";
ClassA.prototype.sayColor = function () {
alert(this.color);
}; function ClassB() {
} ClassB.prototype = new ClassA(); ClassB.prototype.name = "";
ClassB.prototype.sayName = function () {
alert(this.name);
}; var objA = new ClassA();
var objB = new ClassB();
objA.color = "blue";
objB.color = "red";
objB.name = "John";
objA.sayColor();
objB.sayColor();
objB.sayName();

  注意:调用 ClassA 的构造函数,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。

实际应用中,可能混合方式:

(象冒充的主要问题是必须使用构造函数方式,这不是最好的选择。不过如果使用原型链,就无法使用带参数的构造函数了)

在前一章,我们曾经讲解过创建类的最好方式是用构造函数定义属性,用原型定义方法。这种方式同样适用于继承机制,用对象冒充继承构造函数的属性,用原型链继承 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.sayName = function () {
alert(this.name);
}; var objA = new ClassA("blue");
var objB = new ClassB("red", "John");
objA.sayColor();
objB.sayColor();
objB.sayName();

  注意:在第一行突出显示的代码中,在 ClassB 构造函数中,用对象冒充继承 ClassA 类的 sColor 属性。在第二行突出显示的代码中,用原型链继承 ClassA 类的方法。由于这种混合方式使用了原型链,所以 instanceof 运算符仍能正确运行。

作者:杨志
链接:https://www.zhihu.com/question/20289071/answer/14644278
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

LZ要先明白存在call和apply的原因,才能记得牢一点:
在javascript OOP中,我们经常会这样定义:

function cat(){
}
cat.prototype={
food:"fish",
say: function(){
alert("I love "+this.food);
}
}

var blackCat = new cat;
blackCat.say();

但是如果我们有一个对象whiteDog = {food:"bone"},我们不想对它重新定义say方法,那么我们可以通过call或apply用blackCat的say方法:blackCat.say.call(whiteDog);

所以,可以看出call和apply是为了动态改变this而出现的,当一个object没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作。

用的比较多的,通过document.getElementsByTagName选择的dom 节点是一种类似array的array。它不能应用Array下的push,pop等方法。我们可以通过:
var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
这样domNodes就可以应用Array下的所有方法了。

其他的就不提了,讲多了反而迷惑。

 
另外:
  1. JS functions are objects JS函数是对象,没什么特别的
  2. ... that have .call and .apply methods 这些对象只不过有call和apply两个特别的方法而已
  3. ... both take an object as the first argument call和apply的第一个参数是任一个对象
  4. ... which specifies the target where the function runs against 既函数的执行(作用)目标
function fn (a) { ... }
var obj = { ... }
// 在obj上执行fn
fn.call(obj, ...)
fn.apply(obj, ....)

作者:itlr
链接:https://www.zhihu.com/question/20289071/answer/48779872
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 
a)另外:
function add(a, b){console.dir(this);}
function sub(a, b){console.dir(this);}
add(1,2);
"Window"
sub(1,2);
"Window"
add.call(sub, 1, 2);
"sub(a, b)"
sub.apply(add, [1, 2]);
"add(a, b)"

  this和arguments理解了。这2函数apply, call就不攻自破了。

作者:杨佰
链接:https://www.zhihu.com/question/20289071/answer/62582198
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

JavaScript 中实现继承的方式(列举3种在前一章,我们曾经讲解过创建类的最好方式是用构造函数定义属性,用原型定义方法。)的更多相关文章

  1. javascript中各种继承方式的优缺点

    javascript中实现继承的方式有很多种,一般都是通过原型链和构造函数来实现.下面对各种实现方式进行分析,总结各自的优缺点. 一 原型继承 let Super = functioin(name = ...

  2. javascript中实现继承的几种方式

    javascript中实现继承的几种方式 1.借用构造函数实现继承 function Parent1(){ this.name = "parent1" } function Chi ...

  3. JavaScript学习13 JavaScript中的继承

    JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式 ...

  4. 浅谈JavaScript中的继承

    引言 在JavaScript中,实现继承的主要方式是通过原型链技术.这一篇文章我们就通过介绍JavaScript中实现继承的几种方式来慢慢领会JavaScript中继承实现的点点滴滴. 原型链介绍 原 ...

  5. 浅谈 JavaScript 中的继承模式

    最近在读一本设计模式的书,书中的开头部分就讲了一下 JavaScript 中的继承,阅读之后写下了这篇博客作为笔记.毕竟好记性不如烂笔头. JavaScript 是一门面向对象的语言,但是 ES6 之 ...

  6. 深入理解JavaScript中的继承

    1前言 继承是JavaScript中的重要概念,可以说要学好JavaScript,必须搞清楚JavaScript中的继承.我最开始是通过看视频听培训班的老师讲解的JavaScript中的继承,当时看的 ...

  7. JavaScript中的继承(原型链)

    一.原型链 ECMAScript中将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实例1: function SupType() { this.pro ...

  8. 彻底搞懂JavaScript中的继承

    你应该知道,JavaScript是一门基于原型链的语言,而我们今天的主题 -- "继承"就和"原型链"这一概念息息相关.甚至可以说,所谓的"原型链&q ...

  9. 关于JavaScript中实现继承,及prototype属性

    感谢Mozilla 让我弄懂继承. JavaScript有八种基本类型,函数属于object.所以所有函数都继承自object.//扩展:对象,基本上 JavaScript 里的任何东西都是对象,而且 ...

随机推荐

  1. iOS使用NSMutableAttributedString

    在iOS开发中,常常会有一段文字显示不同的颜色和字体,或者给某几个文字加删除线或下划线的需求.之前在网上找了一些资料,有的是重绘UILabel的textLayer,有的是用html5实现的,都比较麻烦 ...

  2. 矩阵类c++实现

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  3. jetty访问jsp页面出现( PWC6345: There is an error in invoking javac)

    org.apache.jasper.JasperException: PWC6345: There is an error in invoking javac.  A full JDK (not ju ...

  4. 在vim中使用perltidy美化perl代码

    来源: http://www.cnblogs.com/itech/archive/2013/02/18/2915279.html 格式优美的perl代码不但让人赏心悦目,而且可以方便阅读. perlt ...

  5. JavaScript CSS Style属性对照表

    JavaScript CSS Style属性对照表 盒子标签和属性对照 CSS语法 (不区分大小写) JavaScript语法 (区分大小写) border border border-bottom ...

  6. ios开发使用lipo命令合并真机库和模拟器库

    在开发ios时,我们经常会遇到编译两套库文件,使用模拟器时链接模拟器库,使用真机时使用真机库,这样操作会对后期的维护带来麻烦,所以Apple提供了一个把多个不同平台的.a库文件合并成一个适用于多平台的 ...

  7. vim 操作(转)

    高效率移动编辑1.在插入模式之外基本上来说,你应该尽可能少的呆在插入模式里面,因为在插入模式里面 VIM 就像一个“哑巴”编辑器一样.很多新手都会一直呆在插入模式里面,因为这样易于使用.但 VIM 的 ...

  8. icecap录屏gif

    百度云下载地址:http://pan.baidu.com/s/1jIeyb4q 之前写博客,只有文字,有些效果看不出来.有了这个gif录屏工具方便很多哦,嘿嘿

  9. java vector 和ArrayList的区别

    相同点: 1.都是使用数组存储数据 不同点: 1.Vector是显示安全的,ArrayList是线程不安全的 Vector部分代码: public synchronized boolean add(E ...

  10. TForm类有关属性简介

    http://www.cnblogs.com/pchmonster/archive/2012/01/02/2310377.html