第一种:对象冒充

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. windows7安装oracle 10g

    1.出现如下错误 解决办法: ①确保你有该文件夹的完全控制权.文件夹点右键->属性->安全->高级->所有者->改为自己->编辑自己的权限为完全控制. ②将setu ...

  2. Ansible5:常用模块【转】

    根据zs官方的分类,将模块按功能分类为:云模块.命令模块.数据库模块.文件模块.资产模块.消息模块.监控模块.网络模块.通知模块.包管理模块.源码控制模块.系统模块.单元模块.web设施模块.wind ...

  3. Anaroid WebView详解大全

    资源描述: 1.android提供了webView控件专门用来浏览网页.然后在程序中装载webView控件,设置属性,比如:颜色.字体.要访问的网址等.通过loadUrl方法设置当前webView需要 ...

  4. HP ProLiant DL380 G6 服务器 - 清 BIOS 的方法

    问题 HP ProLiant DL380 G6服务器的BIOS位置在哪里? 如何清BIOS,具体步骤是什么? 解决方案 DL380 G6服务器清BIOS过程分为三步: 1. 为服务器断电(拔掉电源线) ...

  5. perl的Getopt::Long和pod::usage ?

    来源: http://www.cnblogs.com/itech/archive/2012/08/07/2627267.html 代码: 需要显式地定义变量且初始化.例如optionX. 如果没有定义 ...

  6. 使WiFi具有保存历史连接的功能

    在wpa_supplicant.conf里面添加这个功能 update_config=1 就能更新了,保存了历史的连接AP,不用再输入密码

  7. centos gdb安装

    1. 下载gdb 7.6.1源码包 http://ftp.gnu.org/gnu/gdb/gdb-7.6.1.tar.gz 将源码包放在home目录的Download目录中 2. 解压缩gdb 7.6 ...

  8. WPF中ListBox控件选择多个数据项

    XAML: <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft ...

  9. C++中的基本数据类型

    C++中定义了一组表示整数.浮点数.单个字符和布尔值的算术类型(arithmetic type). 另外还定义了一种叫做void的特殊类型.void类型没有对应的值,仅用在有限的一些情况下,通常用作无 ...

  10. centos7如何关闭防火墙

    1.centos7自带了firewall,而不是iptables: 关闭firewall: service firewalld stop 或者: systemctl stop firewalld 禁止 ...