在学习这篇博文前,请先移步我的另外一篇博文:JS 一张图理解prototype、proto和constructor的关系,先弄清楚“原型链”,这样对于理解继承会非常有效。

注意:博文中提到的“属性”,指的是“属性+方法”,这里统称为“属性”;

一、构造函数继承

var obj = new Object();   使用构造函数new一个对象实例(所以程序员天天都在谈对象,哈哈哈)

特点:

  • 实例对象继承父类的共有属性和私有属性

来个实例加深理解:

function Animal() {
this.type = '动物';
}
Animal.prototype.getType = function(){
console.log(this.type);
}
let animal = new Animal();
console.log(animal.type); // 动物
animal.getType(); // 动物

二、原型链继承

Child.prototype = new Parent();   将父类的实例作为子类的原型

特点:

  • 子类的prototype上的所有属性将被完全覆盖,所以子类的prototype属性应该在覆盖后重新定义;
  • 子类的constructor指向父类,为了构造函数的完整性,需要重新指定子类的constructor属性,方法:Child.prototype.constructor = Child;
  • 修改子类与父类同名的属性,不会修改父类的属性;这是因为父类的属性在子类的原型链上,且这些属性相当于是子类的__prototype__或者更加上一级。(这里如果理解不了,说明没理解透 JS 一张图理解prototype、proto和constructor的关系 这篇文章)
原型继承,并不是把父类的属性和方法COPY一份给子类,而是让子类的原型和父类原型之间搭建一个链接的桥梁,以后子类(或者子类的实例),可以通过原型链的查找机制,找到父类原型上的方法,从而调取这些方法使用即可。

来个实例加深理解:

function Animal() {
this.type = '动物';
}
Animal.prototype.getType = function(){
console.log(this.type);
}
function Cat(){
this.vary = '猫';
}
Cat.prototype.getVary = function(){
console.log(this.vary);
}
Cat.prototype = new Animal();
var cat = new Cat();
// cat.getVary() // 报错:cat.getVary is not a function [原因:Cat.prototype = new Animal()的操作覆盖了原型链]
console.log(cat.constructor); // Animal 这个constructor实质调用的是Animal.prototype.constructor // 修改Cat类的constructor为Cat
Cat.prototype.constructor = Cat;
console.log(cat.constructor); // Cat cat.getType(); // 动物
// 修改Cat类prototype上的getType方法,看是否影响Animal类的getType方法
Cat.prototype.getType = function(){
console.log('我是猫科类');
}
var animal = new Animal();
animal.getType(); // 动物

三、call、apply、bind继承

在子类的构造体中,使用call、apply、bind方法,让父类方法中的this指向子类的实例,也就是改变this的上下文环境。

特点:

  • 子类构造体继承父类的私有属性(继承完成后,子类和父类是没关系的)

先来个call实现原理,很重要的哦

Function.prototype.call2 = function () {
var ary = [...arguments].slice();
if (!arguments[]) {
this(...ary);
} else {
var obj = Object(arguments[]); // 将参数变成一个对象
obj.__proto__.fn = this;
obj.fn(...ary);
delete obj.__proto__.fn;
}
};

来个实例加深理解:

function Animal() {
this.type = '动物';
}
Animal.prototype.getType = function(){
console.log(this.type);
}
function Cat(){
Animal.call(this);
this.vary = '猫';
}
Cat.prototype.getVary = function(){
console.log(this.vary);
}
var cat = new Cat();
console.log(cat.type); // 动物
// cat.getType(); // Uncaught TypeError: cat.getType is not a function
cat.type = '猫科动物';
var animal = new Animal();
console.log(animal.type); // 动物

四、寄生组合继承

var child = Object.create(obj, props);

  • obj:一个对象,应该是新创建的对象的原型。
  • props:可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符

我先来一段Object.create的实现方式(看懂原理很重要)

Object.create =  function (o) {
var F = function () {};
F.prototype = o;
return new F();
};

我们这里只分析参数obj的骚操作,可以看出来,Object.create是内部定义一个对象,并且让F.prototype对象赋值为引进的对象/函数 o,并return出一个对象的实例。

只要看懂了原理,我们可以参考“原型链继承”的方式去理解这种继承方法;

来个实例加深理解:

function Animal() {
this.type = '动物';
}
Animal.prototype.getType = function(){
console.log(this.type);
} var cat = Object.create(new Animal(), {
vary: {
value: '猫科动物'
}
});
console.log(cat.constructor); // Animal 这个constructor实质调用的是Animal.prototype.constructor
console.log(cat.type); // 动物
cat.getType(); // 动物
console.log(cat.vary); // '猫科动物'

JS 详解对象的继承的更多相关文章

  1. 详解Javascript的继承实现(二)

    上文<详解Javascript的继承实现>介绍了一个通用的继承库,基于该库,可以快速构建带继承关系和静态成员的javascript类,好使用也好理解,额外的好处是,如果所有类都用这种库来构 ...

  2. 【three.js详解之一】入门篇

    [three.js详解之一]入门篇   开场白 webGL可以让我们在canvas上实现3D效果.而three.js是一款webGL框架,由于其易用性被广泛应用.如果你要学习webGL,抛弃那些复杂的 ...

  3. 【three.js详解之二】渲染器篇

    [three.js详解之二]渲染器篇   本篇文章将详细讲解three.js中渲染器(renderer)的设置方法. three.js文档中渲染器的分支如下: Renderers CanvasRend ...

  4. dev-server.js详解

    转载自:https://www.cnblogs.com/ye-hcj/p/7091706.html dev-server.js详解 require('./check-versions')() var ...

  5. webpack.dev.conf.js详解

    转载自:https://www.cnblogs.com/ye-hcj/p/7087205.html webpack.dev.conf.js详解 //引入当前目录下的utils.js文件模块var ut ...

  6. JS 详解 Cookie、 LocalStorage 与 SessionStorage-转载

    记录一下这些知识,有时候用到会忘记,对原文作者表达感谢. 附上原文链接:JS 详解 Cookie. LocalStorage 与 SessionStorage 基本概念 Cookie Cookie 是 ...

  7. [js高手之路]深入浅出webpack系列2-配置文件webpack.config.js详解

    接着上文,重新在webpack文件夹下面新建一个项目文件夹demo2,然后用npm init --yes初始化项目的package.json配置文件,然后安装webpack( npm install ...

  8. [js高手之路]深入浅出webpack教程系列3-配置文件webpack.config.js详解(下)

    本文继续接着上文,继续写下webpack.config.js的其他配置用法. 一.把两个文件打包成一个,entry怎么配置? 在上文中的webpack.dev.config.js中,用数组配置entr ...

  9. [js高手之路]深入浅出webpack教程系列2-配置文件webpack.config.js详解(上)

    [js高手之路]深入浅出webpack教程系列索引目录: [js高手之路]深入浅出webpack教程系列1-安装与基本打包用法和命令参数 [js高手之路]深入浅出webpack教程系列2-配置文件we ...

随机推荐

  1. elastic-job详解(四):失效转移

    elastic-job中最关键的特性之一就是失效转移.配置了失效转移之后,如果在任务执行过程中有一个执行实例挂了,那么之前被分配到这个实例的任务(或者分片)会在下次任务执行之前被重新分配到其他正常节点 ...

  2. javascript中的常用表单事件用法

    下面介绍几种javascript中常用的表单事件: 一,onsubmit:表单中的确认按钮被点击时发生的事件,如下案例. 案例解析:弹出表单中提交的内容 <form name="tes ...

  3. GMA Round 1 向量计算

    传送门 向量计算 已知$\left |\overrightarrow{AB} \right |^2+\left |\overrightarrow{CD} \right |^2+\left |\over ...

  4. 利用百度OCR实现验证码自动识别

    在爬取网站的时候都遇到过验证码,那么我们有什么方法让程序自动的识别验证码呢?其实网上已有很多打码平台,但是这些都是需要money.但对于仅仅爬取点数据而接入打码平台实属浪费.所以百度免费ocr正好可以 ...

  5. ASP.NET WebApi 基于OAuth2.0实现Token签名认证

    一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将是我们需要思考的问题.为了保护我们的WebApi数 ...

  6. 广告行业中常说的 CPC,CPM,CPD,CPT,CPA,CPS 等词的意思是什么?

    广告投放流程主要分为展示和转化,CPC/CPM/CPD/CPT/CPA/CPS等代表的是不同的结算模式 展示端的结算方式有: CPM(Cost Per Mille) 每千人成本:只要向足够量级的用户展 ...

  7. nltk 的分词器punkt: ssl问题无法下载

     报错: LookupError: ********************************************************************** Resource pu ...

  8. Linux系统下分析内存使用情况的管理工具

    有许多办法可以获得Linux系统上所安装内存的信息,并查看其中有多少内存正在使用中.有的命令会展示大量的细节,而有的命令则提供了简洁(但不一定容易理解)的结果.在这篇文章中将介绍一些更有用的工具,帮助 ...

  9. Eclipse创建第一个Spring Boot项目

    一.安装SpringBoot插件 安装过程需要联网下载插件,属于在线安装,请耐心等待安装完成,下载安装完成以后,需要重启Eclipse 二.创建Spring Boot项目 如下图所示new-other ...

  10. Nginx配置,413 Request Entity Too Large错误解决

    今天有同事找我,说图片上传之后,不知道去哪里了.分析了一下问题,找到原因之后做了处理,这里简要记录一下. 问题原因: 1.首先后台log并无错误信息: 2.捡查了一下浏览器,发现network中有报错 ...