JS深拷贝继承
所谓深拷贝,就是子对象不紧继承父对象的非引用属性,还能继承父对象的引用属性(Object,Array),当子对象对继承的引用类型属性做修改时,父对象的引用类型不会被修改。
我们先写个浅拷贝的封装函数:
function extendCopy(parent){
var child={};
for(var i in parent){
child[i]=parent[i];
}
child.uber=parent;
return child;
}
接下来写个深拷贝的封装函数:
function deepCopy(p,c){
var c=c||{};
for(var i in p){
if(typeof p[i]==="object"){
c[i]=(p[i].constructor===Array)? [] : {};
deepCopy(p[i],c[i]);
}else{
c[i]=p[i];
}
}
return c;
}
分析两个函数有何不同,extendCopy方法是将父对象的属性和方法逐个的拷贝给子对象,当遇到引用类型的属性时,比如数组,那么若对子对象拷贝而来的数组进行重写时,父对象对应的数组也会随之改变,因为他们指向的是同一地址。
而deepCopy方法:
举个栗子:
var parent={
score:[1,2,3,4];
}
var child=deepCopy(parent);
执行deepCopy函数后,当执行到
if(typeof parent[score]==='object')时,
child[score]=[];
再执行deepCopy(parent[score],child[score]);
此时typeof p[i]就不是'object'类型了,而是number类型,
所以
child[score][1]=parent[score][1]=1;
child[score][2]=parent[score][2]=2;
child[score][3]=parent[score][3]=3;
child[score][4]=parent[score][4]=4;
在return child[score];
这样就完成了深拷贝,child[score]和parent[score]不是指向同一个地址了。但此时两者值相同,只是地址不同,若再对child[score]做修改,parent[score]不会有任何变化。
我们来试验一下:
var Shape={
color:"blue",
name:"shape",
size:[1,2,3,4],
getName:function(){
return this.name;
}
}
var circle=deepCopy(Shape);
var tran=extendCopy(Shape);
circle.size.push(5,6);
console.log(circle.size); //[1,2,3,4,5,6]
console.log(Shape.size);//[1,2,3,4] 深拷贝父对象值没有变化
tran.size.push(5,6,7,8);
console.log(circle.size); //[1,2,3,4,5,6]
console.log(tran.size);//[1,2,3,4,5,6,7,8]
console.log(Shape.size); //[1,2,3,4,5,6,7,8] 浅拷贝随着tran.size的改变,Shape.size也会随之改变,
上述demo很好的验证了浅拷贝和深拷贝的区别
JS深拷贝继承的更多相关文章
- JS对象继承篇
JS对象继承篇 ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的 原型链 其基本思路是利用原型让一个引用类型继承另一个引用类型的属性和方法 function Person() ...
- js实现继承的5种方式 (笔记)
js实现继承的5种方式 以下 均为 ES5 的写法: js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承 ...
- js实现继承的方式总结
js实现继承的5种方式 以下 均为 ES5 的写法: js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承 ...
- 【09-23】js原型继承学习笔记
js原型继承学习笔记 function funcA(){ this.a="prototype a"; } var b=new funcA(); b.a="object a ...
- js实现继承的两种方式
这是面试时面试官会经常问到问题: js的继承方式大致可分为两种:对象冒充和原型方式: 一.先说对象冒充,又可分为3种:临时属性方式.call().apply(): 1.临时属性方式: 当构造对象son ...
- js实现继承
js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承有以下通用的几种方式1.使用对象冒充实现继承(该种实现 ...
- 浅谈JS的继承
JS继承 继承是OO语言中最为人津津乐道的概念,许多OO语言都支持两种方式的继承:接口继承:实现继承. 接口继承:只继承方法签名. 实现继承:继承实际的方法. 由于ES里函数没有签名,所以在ES里面无 ...
- JS类继承常用方式发展史
JS类继承常用方式发展史 涉及知识点 构造函数方式继承 1-继承单个对象 1.1 多步走初始版 1.2 多步走优化版 1.3 Object.create()方式 2-继承多个对象 2.1 遍历 Obj ...
- js 深拷贝和浅拷贝
js 深拷贝和浅拷贝 先举一下项目中遇到的两个例子: 例子1: var json = $.parseJSON(data.data);//data.data是接口返回的值var a = json.cha ...
随机推荐
- Git从码云或者Github 克隆代码到本地
Git从码云或者Github 克隆代码到本地 1.下载安装Git,傻瓜式下一步下一步即可... 2.配置Git: 2.1.选择你要clone到本地的路径:右键--->$ Git Bash Her ...
- XorPay 个人支付平台增加 个人支付宝支付接口
XorPay 今天新增 个人支付宝当面付 接口,欢迎大家使用. 「 XorPay 支付平台」 已经同时支持 个人微信支付接口 和 个人支付宝接口. 个人可用的 支付宝/微信支付 接口,支持 当面付 ...
- CentOS7 安装 Adobe Flash 看网络视频
登录 Adobe 网站,找到 Adobe Flash Player 下载页,进入后网页自动识别 Linux 环境,手动选择版本,选择 YUM 方式,自动下载一个 rpm 文件 定位到下载目录,通常默认 ...
- LOJ3069. 「2019 集训队互测 Day 1」整点计数(min_25筛)
题目链接 https://loj.ac/problem/3069 题解 复数真神奇. 一句话题意:令 \(f(x)\) 表示以原点 \((0, 0)\) 为圆心,半径为 \(x\) 的圆上的整点数量, ...
- 网站安全系列:跨站脚本攻击XSS
本篇博文主要从概念和应用上介绍XSS,主要内容来源于<白帽子讲web安全> XSS核心本质 XSS实际上是一种HTML注入,用户输入的数据被当成HTML的一部分来执行.防御方法核心是输入检 ...
- Elastic-Job源码分析之AbstractElasticJobExecutor分析
还记得我们在JobScheduler中,在创建任务详情时,会调用一个建造器JobBuilder来创建一个Job,类型是LiteJob. LiteJob.java /** * Lite调度作业. * * ...
- java处理数据库的CRUD
package com.lhy.jdbc.util; import java.sql.Connection; import java.sql.PreparedStatement; import jav ...
- js中请求数据的$post和$ajax区别(同步和异步问题)
$.post和$.Ajax都为页面上向后台发送请求,请求数据 1.post 因为post默认为异步请求,可是有时候我们会发现,本来要求请求马上出现,可是异步会导致后面突然再执行,这样就出很多问题 2. ...
- PHP之string之explode()函数使用
explode (PHP 4, PHP 5, PHP 7) explode - Split a string by string explode - 使用一个字符串分割另一个字符串 Descripti ...
- JVM启动报错: Could not reserve enough space for object heap error
首先了解一下参数的含义: 参数 含义 -Xms2G -Xmx2G 代表jvm可用的heap内存最小和最大 -XX:PermSize -XX:MaxPermSize 代表jvm的metadata内存的大 ...