JS 继承

ContextCapture导入点云进行重建 阅读详情

最近在阅读红宝书,刚好重新过来一遍继承,拿来和大家分享下,继承是JS核心之一,面试必问。
在继承之前大家需要了解的就是js创建对象,常见的创建对象方式有工厂模式,构造模式,原型模式。

                    **理解原型对象**

1.只要创建了一个函数,就会为该函数创建一个prototype属性,指向函数的原型对象。
2.原型对象会自动获得一个constructor属性,指向所在的构造函数。
3.每个对象实例都包含一个内部属性,该属性指向原型对象
4.通过构造函数,还可以继续为原型对象添加其他属性和方法。
5.当给对象实例添加一个属性时,这个属性会屏蔽原型对象中保存的同名属性,
即添加这个属性只会阻止我们访问原型中的属性,而不会修改那个属性


最主要的创建对象的方法
组合使用构造函数模式和原型模式

创建自定义类型最常见的方式,定义引用类型的一种默认模式。

思想:

构造函数模式:用于定义实例属性
原型模式:用于定义方法和共享的属性
每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存。支持向构造函数传递参数。

function Person(name,age){
    this.name = name;
    this.age = age;
    this.friends = ["小红","小明"];
}

Person.prototype = {
    constructor : Person,
    getAge : function(){
        console.log(this.age);
    }
}

var zhangsan = new Person("zhangsan",23);
var lisi = new Person("lisi",30);

zhangsan.friends.push("小三");
console.log(zhangsan.friends); //["小红","小明","小三"]
console.log(lisi.friends); //["小红","小明"]
console.log(zhangsan.friends === lisi.friends); //false
console.log(zhangsan.getAge === lisi.getAge); //true

有了以上这些知识我们再来看继承

由于函数没有签名,在ECMAScript中无法实现接口继承,只支持实现继承,而实现继承主要是依靠原型链来实现。

继承:

原型链 借用构造函数 组合继承 原型式继承 寄生式继承 寄生组合式继承

JavaScript主要通过原型链实现继承。使用最多的是组合继承。

原型链:

通过将一个类型的实例赋值给另一个构造函数的原型实现。(问题对象实例共享所有继承的属性和方法,不适宜单独使用)

借用构造函数:

在子类型构造函数的内部调用超类型构造函数。(每个实例都具有自己的属性)

组合继承:

使用原型链继承共享的属性和方法,通过借用构造函数继承实例属性。

原型式继承:

可以不必预先定义构造函数的情况下继承(执行对给定对象的浅复制,复制得到的副本还可以进一步改造)

寄生式继承:

与原型式继承非常相似,也是基于某个对象或某些信息创建一个对象,然后增强对象,返回对象。(为了解决组合继承由于多次调用超类构造函数而导致低效率问题,可将这个模式与组合继承一起使用。)

寄生组合式继承:

集寄生式继承和组合继承的优点与一身,是实现基于类型继承的最有效方式。

原型链

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数想指针(constructor),而实例对象都包含一个指向原型对象的内部指针(proto)。如果让原型对象等于另一个类型的实例,此时的原型对象将包含一个指向另一个原型的指针(proto),另一个原型也包含着一个指向另一个构造函数的指针(constructor)。假如另一个原型又是另一个类型的实例……这就构成了实例与原型的链条。

function animal(){  
    this.type = "animal";  
}  
animal.prototype.getType = function(){  
    return this.type;  
}  

function dog(){  
    this.name = "dog";  
}  
dog.prototype = new animal();  

dog.prototype.getName = function(){  
    return this.name;  
}  

var xiaohuang = new dog();
//原型链关系  
xiaohuang.__proto__ === dog.prototype  
dog.prototype.__proto__ === animal.prototype  
animal.prototype.__proto__ === Object.prototype  
Object.prototype.__proto__ === null  

缺点:

包含引用类型值的原型。
在创建子类型的实例时,不能向超类型的构造函数中传递参数。(没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数)

借用构造函数

优点:

解决原型中包含引用类型值带来的问题。
可以在子类型构造函数中向超类型构造函数传递参数。

思想:
在子类构造函数内部调用超类构造函数。
通过apply()和call()方法可以在新建的对象上执行构造函数。

function Animal(){
    this.colors = ["red","blue"];
}

function Dog(){
    //继承Animal
    Animal.call(this);
}

var xiaohuang = new Dog();
xiaohuang.colors.push("yellow");
console.log(xiaohuang.colors): // ["red","blue","yellow"]

var xiaohei = new Dog();
xiaohei .colors.push("black");
console.log(xiaohei .colors); // ["red","blue","black"]

//Dog的每个实例都会有自己的colors属性副本
//传递参数
//优点:在子类构造函数中向父类构造函数传递参数(相比于原型链的优点)

function Animal(name){
    this.name = name;
}

function Dog(){
    //继承Animal,同时还传递了参数
    Animal.call(this,"xiaohuang");
    this.age = 10; //实例属性
}

var xiaohuang = new Dog();
console.log(xiaohuang .name);  //"xiaohuang”
console.log(xiaohuang .age);    //10

缺点:

构造函数模式存在的问题—方法都在构造函数中定义,函数复用无从谈起。
在超类型的原型中定义的方法,在子类型是不可见的。
结果所有的类型都只能使用构造函数模式
借用构造函数很少单独使用

组合继承

组合继承/伪经典继承–最常用的继承模式

优点:

将原型链和借用构造函数组合到一起,发挥两者之长。
思想:
使用原型链实现对原型属性和方法的继承,(实现了函数的复用)
通过借用构造函数实现对实例属性的继承 (保证每个实例都有自己的属性)

function Animal(name){
    this.name = name;
    this.colors = ["red","blue"];
}

Animal.prototype.getName = function(){
    console.log(this.name);
}

function Dog(name,age){
    //继承属性
    Animal.call(this,name);
    this.age = age;
}

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
Dog.prototype.getAge = function(){
    console.log(this.age);
}

var xiaohuang = new Dog("xiaohuang",10);
xiaohuang.colors.push("yellow");
console.log(xiaohuang.colors); //"red","blue","yellow"
xiaohuang.getAge(); //10
xiaohuang.getName(); //"xiaohuang"

var xiaohei = new dog("xioahei",3);
console.log(xiaohei.colors); //"red","blue"
xiaohei.getAge(); //3
xiaohei.getName(); //"xioahei"

解释:
animal的构造函数定义了name和colors两个属性

dog的原型定义了getName()方法。
dog构造函数在调用animal构造函数时传入了name参数,
又定义了自己的属性age

将animal实例的赋值给dog的原型,又在新原型上添加方法getAge(),两个不同的实例可以分别拥有自己的属性name,colors,又可以使用相同的方法getName()

instanceof,isPrototypeOf()也能够识别基于组合继承创建的对象。

缺点:

无论什么情况下,都会调用两次超类型构造函数。
(1.创建子类原型的时候 2.子类型构造函数内部) 看 寄生组合式继承
有两组 name和colors属性,dog的原型中有,dog的实例中有,实例中会屏蔽原型的的两个同名属性。

原型式继承

思想:
没有严格意义上的构造函数。
借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。
必须要有一个对象可以作为另一个对象的基础。

function object(o){
    function F(){};
    F.prototype = o;
    return new F();
};
//object对传入的对象进行了一次浅复制

var xiaoming = {
    name : "xiaoming",
    friends : ["f1","f2"]
};

var xiaohong = object(xiaoming);

xiaohong.__proto__ === xiaoming; //true
xiaohong.name = "xiaohong";
xiaohong.friends.push("f3");

var xiaohua = "xiaohua";
xiaohua.friends.push("f4");

console.log(xiaoming.friends);//["f1","f2","f3","f4"]

缺点 :

和原型模式一样,包含引用类型值的属性始终都会共享相应的值

寄生式继承

思路:
与寄生构造函数和工厂模式类似,
创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象。

function createAnother(o){
    var clone = object(o);  //通过调用函数创建一个新对象
    clone.sayHi = function(){ //以某种方式来增强这个对象
        alert("hi");
    };
    return clone;  //返回这个对象
}

var person = {
    name : "fangfang",
    friends : ["f1","f2"]
};

var anotherperson = createAnother(person);
anotherperson.sayhi(); //"hi"
//anotherperson具有person的所有属性和方法,还有自己的sayhi方法

缺点:
适用场景:在主要考虑对象,而不是自定义类型和构造函数的情况

寄生组合式继承

最理想的继承方式

优点:

不必为了指定子类型的原型而调用父类型的构造函数(解决了组合继承至少两次调用超类构造函数)
(只调用了一次animal构造函数,避免了dog.prototype上面创建多余的属性)
(还能正常使用instanceof和isPrototypeOf())
思想:
通过借用构造函数来继承属性,
通过原型链的混成形式来继承方法

不必为了指定子类型的原型而调用父类型的构造函数,
我们所需的只是父类原型的一个副本。
就是使用寄生式继承来继承父类的原型,然后将结果指定给子类型的原型

function inheritPrototype(Dog,Animal){
    var prototype = Object(Animal.prototype); //创建父类原型的一个副本
    prototype.constructor = Dog; //副本添加constructor属性
    Dog.prototype = prototype;  //把副本赋值给子类原型
}

function Animal(name){
    this.name = name;
    this.colors = ["red","blue"];
}
Animal.prototype.getName = function(){
    console.log(this.name);
}

function Dog(name,age){
    Animal.call(this,name);
    this.age = age;
}

inheritPrototype(Dog,Animal);

Dog.prototype.getAge = function(){
    console.log(this.age);
}

//此时 Animal.prototype === Dog.prototype

https://github.com/zgfang1993/blog/issues

【MATLAB代码】基于水声通信(ACOMMS)下的到达时间差(TDOA)定位的AUV自主导航例程,附完整代码 水下AUV导航系统仿真研究 本研究基于到达时间差(TDOA)技术实现了水下自主航行器(AUV)的三维导航仿真系统。系统采用四个声学信标作为定位基准,通过TDOA测量数据迭代求解AUV位置。仿真结果表明: 导航性能:系统能够有效跟踪AUV从起点(30,30,-20)到目标点(70,70,-20)的航行轨迹,定位误差保持在合理范围内。 误差分析:定位误差变化曲线显示系统具有稳定的定位精度,平均误差为0.5米左右。 技术特点:采用两步最小二乘迭代算法求解非线性TDOA方程,提高了定位精度和计算效率。 该仿真系统为 阅读详情

相关推荐

rk3568 rockit编译测试

编译rockit不能使用SDK默认编译kernel的交叉编译,需要采用编译buildroot的,而编译buildroot的编译器SDK并没有存放,需要编译过buildroot之后才可以用。命令参数相关解析可查阅代码,这里提醒一下-l参数,这是程序运行计数,默认是100,时间很短,基本上显示画面一闪而过,一度以为是程序哪里出问题了,改用-l 1000,画面显示时间加长。此处跳过系统,单领出来编译。rockit组件包在4.10版本需要手动编译,奈何我的版本怎么都编译不了,后来改用5.10版本才编译通过。

zfenggo的博客 4197

【JavaScript】js中的原型继承

js中的原型继承

南栀的博客 3705

雷电模拟器+Auto.js避坑指南:用桥接模式解决PC与模拟器连接超时问题

本文详细解析了雷电模拟器与Auto.js联调中的桥接模式应用,解决PC与模拟器连接超时问题。通过桥接模式配置、高频故障排查及多开环境下的高阶配置,提升开发效率与稳定性,特别适合需要稳定网络连接的Auto.js开发者。

weixin_28836989的博客 632

JS的继承 ES5;javascript的继承;

基础概念 说继承之前简单介绍一下,几个概念,有助于更深刻的理解继承。 能用口述或者文字的形式,说一下什么是函数吗? 按照犀牛书的说法,函数简单的说就是重复执行的代码块。函数是这样的一段JavaScript 代码,它只定义一次,但可能被执行或调用任意次。 //使用方式 //1.直接声明 function(){} //2.函数表达式 let fun = function(){} //3. new Function() var fun1 = new Function (arg1 , arg2 ,arg3 ,…

HeMister的博客 1174

FPGA资料分享——FPGA开发板入手指南

FPGA学习,开发板怎么选,看这里,就一个通透

weixin_51627076的博客 7298

Adversarial Texture for Fooling Person Detectors in the Physical World

本文提出了对抗纹理的想法(AdvTexture),与基本补丁攻击不同对抗纹理可以生成任意大小,可以覆盖任意大小的不了,并且纹理的任何局部都有对抗性的效果。当衣服被对抗纹理覆盖是,摄像头捕捉到的每一个局部区域都可以攻击探测器,这成功解决了片段缺失的问题。提出了一种两阶段生成方法:基于环形收割的可扩展生成攻击(TC-EGA)来制作广告纹理。第一阶段,训练一个全卷积网络FCN作为生成器,通过采样随机潜变量作为输入来产生纹理(不同于GAN中传统的生成器架构,每一层都使用卷积运算)......

weixin_49171105的博客 1067

[JavaScript]js有哪些继承方式

js继承的方法 想要继承,就必须先提供一个父类,这里以Person来作为父类举例 function Person(name){//给构造函数添加了参数 this.name=name; this.sex="male"; this.say=function(){ console.log(this.name); } } Person.pr

DaftJayee的博客 501

Notion卡顿救星:3分钟搞定DNS优化,手机电脑全平台加速指南

本文针对Notion访问慢和卡顿问题,提供了全平台DNS优化与Hosts文件修改的详细指南。通过更换优质DNS服务器或建立静态IP映射,可有效解决因网络延迟和域名解析导致的加载缓慢,实现手机与电脑端的快速加速,提升Notion使用流畅度。

v6b7n8m9q0的博客 1306

javascript继承、js继承实现方式、js继承优缺点

有如下父类 function People(name,age){ this.name = name this.age = age this.seelp = function(){ console.log('i am seelp') } } People.prototype.eat = function(){ console.log('i can eat') } 原型链继承 原理: 子类 的 prototype = 父类 的 实例 优点: 简单 不占

xiao_yu_liu的博客 266

Python爬虫实战:爬取小红书数据做爆款分析,我破解了签名加密+移动端反爬(附完整代码)

爬取小红书数据的核心,不是“简单的HTTP请求”,而是“理解移动端接口的加密逻辑和反爬规则”——从x-s/x-t签名破解到移动端UA伪装,再到行为模拟,每一步都是对移动端爬虫的深度理解。这套方案的价值在于,不仅能稳定抓取小红书数据,还能从数据中拆解出有价值的爆款特征,真正把“数据”变成“洞察”。对程序员来说,小红书爬虫不仅是技术练手,更是了解新媒体平台数据逻辑的窗口。希望这篇分享能帮到做新媒体分析或爬虫进阶的小伙伴,也欢迎在评论区交流小红书反爬和爆款分析的更多技巧!

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2058

如何创建 SAP ABAP CDS View 的 Association

所以本文我们虽然学习了如何创建 SAP CDS View 的 association,知道了 association 是用来在 CDS View 里将两张数据库表关联起来,但根本不知道怎么使用这个 association. 而且从 association 的写法来看,似乎和本教程之前介绍 inner join,left join 这些数据库表的连接操作没什么区别,都是根据两张表的 carrid 和 connid 字段相同进行的连接。只看到了我们在 CDS View 源代码实现里,放出来的四个字段。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 904

JavaScript(十七)JS的四种继承方法

JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一。JS面向对象知识中,继承是比较难比较抽象的一块内容,而且实现继承有很多种方法,每种方法又各有优缺点,需要对面向对象知识中的对象、原型、原型链、构造函数等基础知识掌握透彻,下面我们介绍四种继承的方法:原型链继承,构造继承,实例继承,组合继承。 既然要实现继承,那么首先我们得有一个父类,代码如下: /*先定义一个父类对象*/ ...

We_jia的博客 253

【华为OD机试真题E卷】514、学生方阵 | 机试真题+思路参考+代码分析(E卷复用)(C++、Java、Py)

【华为OD机试真题E卷】514、学生方阵 | 机试真题+思路参考+代码分析(E卷复用)(C++、Java、Py) 题目描述 学校组织活动,将学生排成一个矩形方阵 请在矩形方阵中找到最大的位置相连的男生数量 这个相连位置在一个直线上,方向可以是水平的,垂直的,成对角线的或者呈反对角线的 注:学生个数不会超过10000

KJ.JK 2492

JS实现继承 JavaScript

JS实现继承 JavaScript 定义一个父类: // 定义一个动物类 function Animal (name) { // 属性 this.name = name || ‘Animal’; // 实例方法 this.sleep = function(){ console.log(this.name + ‘正在睡觉!’); } } // 原型方法 Animal.prototype.eat =...

hellogril前端库 151

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

javaScript---js如何实现继承

js实现继承的方法:构造函数继承、原型链继承、组合继承、class继承、实例继承 、拷贝继承 、寄生组合继承。

maidu_xbd的博客 735

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

js之三种继承方式

我要成为这次疫情期间,最闲得码农!!!! 一、为什么要有JS继承 假如每一个实例对象,都要有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费。(这就和我们现实中会继承父母的资产一样,你是可以选择不继承的,但是浪费钱啊) 二、JS继承的三种方式 1.原型继承 //构建一个父类 function Person(name) {...

weixin_44395929的博客 501

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

【JavaScript】js中如何实现继承?

下面以一张图作为总结:通过来划分不同的继承方式,最后的寄生式组合继承方式是通过组合继承改造之后的最优继承方式,而extends的语法糖和寄生组合继承的方式基本类似。

一个前端开发者 319

JavaScript对象继承新纪元:js-dejavu深度指南

JavaScript对象继承新纪元:js-dejavu深度指南 项目介绍 js-dejavu 是一个面向JavaScript开发者的强大库,旨在简化原型继承模型,引入经典继承模式,使得在JavaScript中实现面向对象编程更为直观与高效。对于那些习惯了Java、ActionScript 3.0等语言的对象继承机制的开发者来说,它提供了一种过渡到JavaScript复杂原型链世界的桥梁。js-de...

gitblog_00859的博客 1375

JavaScript 继承 | 我学到的JS五种继承方式

文章目录1. 构造继承1.1 构造继承的优点1.2 构造继承的缺点2. 原型继承2.1 原型链继承的优点2.2 原型链继承的缺点3. 复制继承3.1 复制继承的优点3.2 复制继承的缺点4. 组合继承4.1 组合继承的优点4.2 组合继承的缺点5. 寄生组合继承(完美级)5.1 寄生组合继承的优点5.2 寄生组合继承的缺点6 学习小结 1. 构造继承 核心思想:在子类的构造函数中通过call()函数或apply()函数改变this的指向,调用父类的构造函数,实现继承效果 // 示例代码 // 父类 f

是希望的博客 215

Ring.js - JavaScript 中的多继承类系统

Ring.js - JavaScript 中的多继承类系统 1. 项目基础介绍及主要编程语言 Ring.js 是一个开源的 JavaScript 类系统,支持多继承。它旨在让开发者能够以类似于 Java、Python 等传统面向对象编程语言的方式,在 JavaScript 中实现类和继承机制。项目主要使用 JavaScript 编写,同时包含一些 HTML 和 YAML 文件以支持文档和自动化测试...

gitblog_00906的博客 354

JavaScript强化教程——Cocos2d-JS中JavaScript继承

本文为 H5EDU 机构官方 HTML5培训 教程,主要介绍:JavaScript强化教程 —— Cocos2d-JS中JavaScript继承   JavaScript语言本身没有提供类,没有其它语言的类继承机制,它的继承是通过对象的原型实现的,但这不能满足Cocos2d-JS引擎的要求。由于Cocos2d-JS引擎是从Cocos2d-x演变而来的,在Cocos2d-JS的早期版本Coc

bright_mmmmmmmmmmmm的专栏 451

javaScript-js的继承

javaScript-js的继承组合继承寄生组合式继承(常用) 组合继承 组合继承(组合原型链继承和借用构造函数继承)(常用) function Person(name){ this.name = name this.drop = function(){ console.log(this.name + " 跳下去"); } } Person.prototype.say = function(){

weixin_47402645的博客 221

JavaScript——JS继承(个人学习)

ES5 有 6 种方式可以实现继承 原型链继承、借用构造函数、组合继承(原型链+借用构造函数)、原型式继承、寄生式继承、寄生组合式继承 ES6 实现继承 文章目录前言一、原型链继承1. 缺点:二、借用构造函数1.优点2.缺点三、组合继承(原型链+借用构造函数)1.优点2.缺点1.缺点五、寄生式继承1.缺点六、寄生组合式继承寄生组合式继承的基本模式1.优点七、ES6 实现继承总结 前言 前因:ECMAScript不支持接口继承,只支持实现继承 提示:以下供个人学习专用,可参考 一、原型链继承 利用原

weixin_47295135的博客 472
上一篇: 移动端页面适配方案
下一篇: JS 闭包
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值