继承

父类里有些属性方法 子类想把父类中的这些属性方法 继承过来给子类自己的实例也用用

( ps: →_→ 能不能专业点 没文化真可怕 )

一、原型链继承

   // 原型链继承:把子类的原型作为父类的实例
// 子类把父类中的私有和公有 都继承过来作为子类的原型属性(公有的)
function A() {
this.a = 123;
this.say = function () {
console.log('say');
}
}
A.prototype.mess = 'mess';
B.prototype = new A; // 将子类 的原型对象 重构为 父类A的实例
B.prototype.constructor = B;
console.log(B.prototype instanceof A);
console.log(B.prototype.__proto__ === A.prototype);
function B() {
}
var b1 = new B;
var b2 = new B;
console.log(b1);
console.log(b1.a);
console.log(b1.say === b2.say); //这个原型属性 是从父类的私有属性中继承过来的
console.log(B.prototype.__proto__ === A.prototype);
// 多态 子类重写父类 导致父类中所有实例都会受到影响
B.prototype.__proto__.mess = '已经被子类修改了'; var a1 = new A;
console.log(a1.mess); 复制代码

二、借用构造函数

// 借用构造函数
// 把父类构造函数当做普通函数执行 将里面this修改为B类中实例
// 这样的话父类中this.xxx 就相当于给我子类实例添加私有属性
// 只能继承父类中私有属性
function A() {
this.a = 123;
this.say = function () {
console.log('say');
}
}
A.prototype.mess = 'mess';
function B() { // 子类中this 当前实例(子类的实例)
A.call(this); // 把父类构造函数当做普通函数执行 将里面this修改为B类中实例
}
var b = new B;
console.log(b);
console.log(b.a); 复制代码

三、组合继承

// 组合继承:原型链+借用构造函数继承
// 原型链:把父类私有和公有 都继承为子类的公有属性
// 借用构造函数:只能继承父类私有属性
// 组合继承 缺点
// 1.子类会把父类的实例属性继承过来两组 一组作为子类实例的私有属性 一组作为子类的公有属性
// 2.父类会被调用俩次
function A() {
console.log(2222);
this.a = 123;
this.say = function () {
console.log('say');
}
}
A.prototype.mess = 'mess';
B.prototype = new A; // 继承父类中原型属性(继承公有) 原型链继承是执行一次
B.prototype.constructor = B;
function B() {
A.call(this); // 继承父类私有的 call继承时执行一次
}
var b = new B;
console.log(b);
console.log(b.a);
console.log(b.mess); 复制代码

四、原型式继承

    // 原型式继承
// Object.create(); 创建一个新对象 然后 让这个新对象的__proto__指向这个传递进来的参数对象
var obj1 = {name: 2, id: 1};
var obj2 = Object.create(obj1); // obj2.__proto__ = obj1;
// console.log(obj2.name);
Object.myCreate = function (o) {
// 创建一个临时构造函数
function Fn() {
}
// 让这个临时构造函数 原型等于传递进来的对象
Fn.prototype = o; // A.prototype
return new Fn; // 返回这临时构造函数的实例 Fn的实例__proto__ = o
};
function A() {
this.a = 123;
this.say = function () {
console.log('say');
}
}
A.prototype.mess = 'mess';
// B.prototype = Object.create(A.prototype); // 创建一个新对象(并不是直接返回的A类的实例)作为子类的原型对象 并且这个对象__proto__ = A.prototype;
// 继承父类公有的属性 作为 子类的公有属性
// 将子类的 原型对象重构为 这个Fn的实例对象 并且这个实例__proto__ = A.prototype
B.prototype = Object.myCreate(A.prototype);
B.prototype.constructor = B; function B() { }
var b = new B;
console.log(b); 复制代码

五、寄生组合继承

    // 寄生组合继承 借用构造函数 + 原型式继承
// 弥补 组合继承的缺点
Object.myCreate = function (o) {
function F() {
}
F.prototype = o;
return new F;
};
function A() {
this.a = 123;
this.say = function () {
console.log('say');
}
}
A.prototype.mess = 'mess';
// 通过原型式继承 将父类的 公有属性 继承为子类的公有属性
// B.prototype = Object.create(A.prototype);
B.prototype = Object.myCreate(A.prototype);
B.prototype.constructor = B;
function B() {
A.call(this); // 将父类的私有属性继承为子类的实例的私有属性
}
var b = new B;
console.log(b); 复制代码

六、冒充对象继承


// 冒充对象继承:在子类构造函数中 生成一个父类的实例 然后把父类的实例当做一个普通对象 进行遍历 将遍历出来的私有和公有 复制一份 作为 子类的私有属性
// 把父类的公有和私有 继承过来作为子类的私有属性
function A() {
this.a = 123;
this.say = function () {
console.log('say');
}
}
A.prototype.mess = 'mess';
function B() {
var temp = new A;
for(var k in temp){
this[k] = temp[k];
}
}
var b = new B;
console.log(b) 复制代码

七、中间类继承

// 中间类 IE 屏蔽了
var arr = [11,22,13,14];
arr.shift();
console.log(arr.__proto__ === Array.prototype);
console.log(arr.shift); // 通过arr的原型链能够找到这个方法
console.log(arr instanceof Array);
function sum() {
arguments.__proto__ = Array.prototype;
// console.log(arguments instanceof Array);
console.log(arguments.shift());
}
sum(1,34,5,6,5)
复制代码

八、ES6继承


class Sub extends Super {
constructor() {
super()
}
} 复制代码

ES6继承其实是 寄生组合式继承实现,并将子类__proto__ 指向了父类本身

"use strict";

// 检验当前构造函数是否是通过new关键字调用
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
} function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
} // 实现继承
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
// 寄生组合继承
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
// 子类__proto__指向父类
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
} var Child = function (_Super) {
_inherits(Child, _Super); function Child() {
_classCallCheck(this, Child); // call继承
return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this));
} return Child;
}(Super); 复制代码

ES6方法 设置原型对象 Object.setPrototypeOf

// 仅适用于Chrome和FireFox,在IE中不工作:
Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
obj.__proto__ = proto;
return obj;
} 复制代码

Object.create(proto, [propertiesObject]) 创建一个对象 并且这个对象的__proto__指向第一个参数proto

let obj1 = {id: 1}
let obj2 = Object.create(obj1) console.log(obj2.__proto__ === obj1) // true
复制代码

JavaScript面向对象那些东西-继承的更多相关文章

  1. JavaScript面向对象中的继承

    1.1继承的基本概念 使用一个子类,继承另一个父类,那么子类可以自动拥有父类中的所有属性和方法,这个过程叫做继承. >>>继承的两方,发生在两个类之间. 实现继承的三种方式: 扩展O ...

  2. Javascript面向对象(封装、继承)

    Javascript 面向对象编程(一):封装 作者:阮一峰 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程( ...

  3. JavaScript 面向对象 原型(prototype) 继承

    1.对象的概念:无需属性的集合,属性可以为数值,对象或函数,ECMAscript中没有类的概念,这点是javascript与其他面向对象(OO)语言不同的地方. //创建一个自定义对象 var per ...

  4. JavaScript面向对象之类的继承

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. Javascript 面向对象编程

    Javascript是一个类C的语言,他的面向对象的东西相对于C++/Java比较奇怪,但是其的确相当的强大,在 Todd 同学的“对象的消息模型”一文中我们已经可以看到一些端倪了.这两天有个前同事总 ...

  6. Javascript 面向对象编程—继承和封装

      前  言 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类) ...

  7. JavaScript面向对象—继承的实现

    JavaScript面向对象-继承的实现 前言 面向对象的三大特性:封装.继承和多态.上一篇我们简单的了解了封装的过程,也就是把对象的属性和方法封装到一个函数中,这一篇讲一下JavaScript中继承 ...

  8. Javascript面向对象特性实现封装、继承、接口详细案例——进级高手篇

    Javascript面向对象特性实现(封装.继承.接口) Javascript作为弱类型语言,和Java.php等服务端脚本语言相比,拥有极强的灵活性.对于小型的web需求,在编写javascript ...

  9. javascript面向对象系列第三篇——实现继承的3种形式

    × 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...

随机推荐

  1. MyBatis(一):第一个MyBatis程序

    本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出1便就懂!b站搜索狂神说即可 https://space.bilibili.com/95256449?spm_id_from=333.788 ...

  2. Vulnhub webdeveloper靶机渗透

    信息搜集 nmap -sP 192.168.146.0/24 #主机发现 nmap -A 192.168.146.148 #综合扫描 访问一下发现是wordpress,wp直接上wpscan wpsc ...

  3. Python+Tornado开发微信公众号

    本文已同步到专业技术网站 www.sufaith.com, 该网站专注于前后端开发技术与经验分享, 包含Web开发.Nodejs.Python.Linux.IT资讯等板块. 本教程针对的是已掌握Pyt ...

  4. leetcode c++做题思路和题解(5)——堆的例题和总结

    堆和优先队列 堆的简介, 是一种二叉树, 有最大堆和最小堆miniheap. 通常用于构建优先队列. 0. 目录 数据流中的第K大元素 1. 数据流中的第K大元素 数据流中的第K大元素 复杂度为log ...

  5. 算法竞赛 从c到c++3

    const 常指针,指向固定位置,不能再次修改指向的位置,需要初始化,const 加在“*”号后面,名称前面,例如 int *const p: 指向常量的指针,不能修改指向地址的内容,相当于常引用,c ...

  6. Linux-设备-磁盘

    磁盘的每个扇区为512bytes.磁盘的第一个扇区记录了整块磁盘的重要信息,包含有主引导分区(MBR):可以安装引导加载程序的地方,有446bytes:分区表(partition table):记录整 ...

  7. Python发送http请求时遇到问题总结

    1.报错信息为“ERROR 'str' object has no attribute 'endwith'”,排查发现endswith方法名写错了,少了s,写成了 'endwith' if inter ...

  8. CTR学习笔记&代码实现3-深度ctr模型 FNN->PNN->DeepFM

    这一节我们总结FM三兄弟FNN/PNN/DeepFM,由远及近,从最初把FM得到的隐向量和权重作为神经网络输入的FNN,到把向量内/外积从预训练直接迁移到神经网络中的PNN,再到参考wide& ...

  9. Problem E. Bet

    转载:https://blog.csdn.net/qq_40861916/article/details/84403731 #include<iostream> #include<c ...

  10. 基于scrapy框架输入关键字爬取有关贴吧帖子

    基于scrapy框架输入关键字爬取有关贴吧帖子 站点分析 首先进入一个贴吧,要想达到输入关键词爬取爬取指定贴吧,必然需要利用搜索引擎 点进看到有四种搜索方式,分别试一次,观察url变化 我们得知: 搜 ...