JS中5种经典继承方式
继承
JS中继承的概念:
- 通过【某种方式】让一个对象可以访问到另一个对象中的属性和方法,我们把这种方式称之为继承
并不是所谓的xxx extends yyy
为什么要使用继承?
- 有些对象会有方法(动作、行为),而这些方法都是函数,如果把这些方法和函数都放在构造函数中声明就会导致内存的浪费
function Person(){
this.say=function(){
console.log("你好")
}
}
var p1=new Person();
var p2=new Person();
console.log(p1.say === p2.say); //false
继承的第一种方式:原型链继承1
Person.prototype.say=function(){
console.log("你好")
}
- 缺点:添加1、2个方法无所谓,但是如果方法很多会导致过多的代码冗余
继承的第二种方式:原型链继承2
Person.prototype = {
//切记不能忘记
constructor:Person,
say:function(){
console.log("你好");
},
run:function(){
console.log("正在进行百米冲刺");
}
}
- 注意点:
- a、一般情况下,应该先改变原型对象,再创建对象
- b、一般情况下,对于新原型,会添加一个constructor属性,从而不破坏原有的原型对象的结构
继承的第三种方式:拷贝继承(混入继承:mixin)
- 场景:有时候想使用某个对象中的属性,但是又不能直接修改它,于是就可以创建一个该对象的拷贝
- 实际运用:
- jquery:$.extend:编写jquery插件的必经之路
- 基于jquery封装一个表格控件
- jquery:$.extend:编写jquery插件的必经之路
var o1={ age:2 };
var o2 = o1;
o2.age=18;
//1、修改了o2对象的age属性
//2、由于o2对象跟o1对象是同一个对象
//3、所以此时o1对象的age属性也被修改了
var o3={gender:"男",grade:"初三",group:"第五组",name:"张三"};
var o4={gender:"男",grade:"初三",group:"第五组",name:"李四"};
//上述代码中,如果使用拷贝继承对代码进行优化会非常和谐
//实现拷贝继承:
//1、已经拥有了o3对象
//2、创建一个o3对象的拷贝(克隆):for...in循环
//3、修改克隆对象,把该对象的name属性改为"李四"
- 实现1:
var source={name:"李白",age:15}
var target={};
target.name=source.name
target.age=source.age;
浅拷贝和深拷贝
- 浅拷贝只是拷贝一层属性,没有内部对象
- 深拷贝其实是利用了递归的原理,将对象的若干层属性拷贝出来
var students=[
{name:"",age:""},
{name:"",age:""}
]
上面的方式很明显无法重用,实际代码编写过程中,很多时候都会使用拷贝继承的方式,所以为了重用,可以编写一个函数把他们封装起来:
function extend(target,source){
for(key in source){
target[key]=source[key];
}
return target;
}
extend(target,source)
由于拷贝继承在实际开发中使用场景非常多,所以很多库都对此有了实现
- jquery:$.extend
es6中有了 <对象扩展运算符> 仿佛就是专门为了拷贝继承而生:
- 优点:简单的令人发指
var source={name:"李白",age:15}
//让target是一个新对象,同时拥有了name、age属性
var target={ ...source }
var target2={ ...source,age:18 }
继承的第四种方式:原型式继承:(道格拉斯在蝴蝶书中提出来的)
- 场景:
- a、创建一个纯洁的对象:对象什么属性都没有
- b、创建一个继承自某个父对象的子对象
var parent={ age:18,gender:"男"};
var student=Object.create(parent);
//student.__proto__===parent
- 使用方式:
- 空对象:Object.create(null)
var o1={ say:function(){} }
var o2=Object.create(o1);
继承的第五种方式:借用构造函数实现继承
- 场景:适用于2种构造函数之间逻辑有相似的情况
- 原理:函数的call、apply调用方式
function Animal(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
function Person(name,age,gender,say){
this.name=name;
this.age=age;
this.gender=gender;
this.say=function(){
}
}
局限性:Animal(父类构造函数)的代码必须完全适用于Person(子类构造函数)
以上代码用借用构造函数实现
function Animal(name,age){
this.name=name;
this.age=age;
}
function Person(name,age,address){
Animal.call(this,name);
//this.name=name;
//this.age=age;
this.address=address;
}
- 寄生继承、寄生组合继承...
JS中5种经典继承方式的更多相关文章
- JS中三种字符串连接方式及其性能比较
工作中经常会碰到要把2个或多个字符串连接成一个字符串的问题,在JS中处理这类问题一般有三种方法,这里将它们一一列出顺便也对它们的性能做个具体的比较. 第一种方法 用连接符“+”把要连接的字符串连起来 ...
- 详解js中的寄生组合式继承
寄生组合式继承是js中最理想的继承方式, 最大限度的节省了内存空间. js中的寄生组合式继承要求是: 1.子对象有父对象属性的副本, 且这些不应该保存在子对象的prototype上. 2. ...
- js中的原型、继承的一些想法
最近看到一个别人写的js类库,突然对js中的原型及继承产生了一些想法,之前也看过其中的一些内容,但是总不是很清晰,这几天利用空闲时间,对这块理解了一下,感觉还是有不通之处,思路上没那么条理,仅作为分享 ...
- [转]js中几种实用的跨域方法原理详解
转自:js中几种实用的跨域方法原理详解 - 无双 - 博客园 // // 这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同 ...
- 关于js中两种定时器的设置及清除(转载)
1.JS中的定时器有两种: window.setTimeout([function],[interval]) 设置一个定时器,并且设定了一个等待的时间[interval],当到达时间后,执行对应的方法 ...
- mybatis中两种取值方式?谈谈Spring框架理解?
1.mybatis中两种取值方式? 回答:Mybatis中取值方式有几种?各自区别是什么? Mybatis取值方式就是说在Mapper文件中获取service传过来的值的方法,总共有两种方式,通过 $ ...
- js中三种定义变量 const, var, let 的区别
js中三种定义变量的方式const, var, let的区别 1.const定义的变量不可以修改,而且必须初始化. 1 const b = 2;//正确 2 // const b;//错误,必须初始化 ...
- JS中几种常见的数组算法(前端面试必看)
JS中几种常见的数组算法 1.将稀疏数组变成不稀疏数组 /** * 稀疏数组 变为 不稀疏数组 * @params array arr 稀疏数组 * @return array 不稀疏的数组 */ f ...
- [js]js中4种无节操的预解释情况
js中4种无节操的预解释情况 - 1. if语句即使条件不成立,条件里的表达式也会进行预解释. - 2. 匿名函数的预解释: 只对等号左边与解释 - 3. 自执行函数的预解释: 不进行预就解释, 执行 ...
随机推荐
- (双指针 二分) leetcode 167. Two Sum II - Input array is sorted
Given an array of integers that is already sorted in ascending order, find two numbers such that the ...
- Flash设置(各种版本浏览器包括低版本IE)
涉及到的各种版本flash百度下都能下到的,不再说明. Flash的安装比较麻烦,涉及多种浏览器.多种操作系统支持,安装.设置的地方比较多,以下说明基本涉及大部分安装过程中可能遇到的问题,如果安装或视 ...
- URL存在跨站漏洞http host头攻击漏洞解决方案
最近项目部署的时候客户使用的绿盟扫描出一些漏洞,老大让我处理,经过看大神的博客等方式,分享一些简单的解决方法. 一 跨网站脚本 跨网站脚本(Cross-site scripting,通常简称为XSS或 ...
- 一张图11招学会Python网络黑客
全部学起来: 第一招:搭建Python防范环境 第二招:扫描漏洞 第三招:暴力破解的秘密 第四招:防SQL注入 第五招:防命令注入 第六招:看清文件上传木马 第七招:看清Web攻击 第八招:利用Pyt ...
- springBoot和Mybatis输出sql日志
利用slf4j来输出日志. 首先需要版本兼容的slf4j-log4j12.log4j.slf4j-api.slf4j-nop.slf4j-simple这5个包. 可以去maven知识库中找到这5个包的 ...
- c51的学习
1.点亮发光二极管,8个发光管由上至下间隔1秒流动,其中每个管亮500没事, 灭500ms,亮时蜂鸣器响,灭时关闭蜂鸣器,一直重复下去 . #include<reg52.h>#includ ...
- 10、jstl标签库
一.JSTL是SUN公司制定的一个JSP标签库,由apache jakarta组织负责维护的开源项目,目的是用标签代替java代码片段.JSTL 1.0 由四个定制标记库(core.format.xm ...
- 在Ubuntu/CentOS/Debian系统下,使用CPU挖Monero (XMR)币
CentOS7(增加源) yum repolist # 查看yum源列表 yum localinstall http://dl.fedoraproject.org/pub/epel/7/x86_64/ ...
- luogu P5319 [BJOI2019]奥术神杖
传送门 要求的东西带个根号,这玩意叫几何平均数,说到平均数,我们就能想到算术平均数(就是一般意义下的平均数),而这个东西是一堆数之积开根号,所以如果每个数取对数,那么乘法会变成加法,开根号变成除法,所 ...
- 只要三步,使用html5+js实现像素风头像生成器
只要三步,使用html5+js实现像素风头像生成器 html5的画布给我们带来了很大的空间,其实像素风格头像生成器只是用到了画方块的方法.画一个像素头像,只要三步,1.解决像素点,2.解决像素点之间的 ...