资讯专栏INFORMATION COLUMN

JavaScript-如何实现克隆(clone)函数

JasonZhang / 3196人阅读

摘要:前提知识在实现克隆函数之前你需要明白以下一些概念如果你已经明白了请直接阅读实现部分什么是值类型引用类型很多新手可能会对值类型引用类型原始类型基本类型等等名称感到困惑这里就解释一下这些概念一个事物是可以有多种区分形式的比如猫我们可以说它是猫科

前提知识

在实现克隆函数之前,你需要明白以下一些概念,如果你已经明白了,请直接阅读 “实现” 部分.

什么是值类型、引用类型?

很多新手可能会对 “值类型”、“引用类型”、“原始类型”、“基本类型”等等名称感到困惑. 这里就解释一下这些概念.

一个事物是可以有多种区分形式的.

比如,猫,我们可以说它是猫科动物,也可以说它是哺乳动物,也可以说它是食肉动物.

在编程语言的世界里也是一样的.

在JavaScript的世界里, 数据被定义为以下 7 种 数据类型 :

6种 原始类型(又叫 基本类型):

Boolean

Null

Undefined

Number

String

Symbol

和 Object

(需要注意的是, 名词从英文翻译成中文,可能会出现多种叫法,比如“primitive type”,中文叫 “原始类型”,也有叫“基本类型”.)

另外,根据变量值传递的方式,我们又可以将数据区分为“值类型”和“引用类型”.

值类型 : 数据在传递和赋值时,数据将自己复制一份给对方.

JavaScript中原始类型都属于值类型(string, number, boolean, null, undefined, symbol).

引用类型 : 在传递和赋值时, 数据将自身的引用(又叫“地址”、“指针”)给对方.

JavaScript中数组、函数、自定义对象,三种属于引用类型.

更详细的解释请阅读: //TODO: (新建文章,介绍 值类型、引用类型)

实现

引用类型数据都是由原始类型数据组成的,因此我们可以将引用类型数据一层层往下拆, 将里面的每一个原始类型数据赋值给新对象.

基于上述思路,我们主要对 数组、函数、自定义对象 这些引用类型的数据进行特殊处理,

Object.prototype.clone = function(){  
        var copy = this.constructor === Array ? [] : {}; //#1

        for(var e in this){
                if (typeof this[e]  === "object") { //#2
                    copy[e] =  this[e].clone(); 
                } else if (typeof this[e]  === "function") { //#3
                    copy[e] =   this[e].bind(copy); //#5
                } else { //#4
                    copy[e] =  this[e]; 
                }
        }

        return copy;
      }

#1: 判断传入的对象是数组类型的对象,还是其它类型的对象.
#2、#3: Array 和 Object 的 typeof是 “object”, Function 的typeof 是“function”. 它们都是引用类型,因此特殊处理.

//typeof 用于引用类型的数据
typeof Array(); // "object"
typeof Object(); // "object"
typeof function(){}; // "function" 

#4: 原始类型直接赋值.
#5: 创建一个新的函数,并且将新函数与 copy 对象绑定.

参考资料:

JavaScript 数据类型和数据结构
Difference between a Value Type and a Reference Type
Javascript之实现一个clone克隆函数
JavaScript: clone a function
Function.prototype.bind()

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101947.html

相关文章

  • [译] 为什么原型继承很重要

    摘要:使用构造函数的原型继承相比使用原型的原型继承更加复杂,我们先看看使用原型的原型继承上面的代码很容易理解。相反的,使用构造函数的原型继承像下面这样当然,构造函数的方式更简单。 五天之前我写了一个关于ES6标准中Class的文章。在里面我介绍了如何用现有的Javascript来模拟类并且介绍了ES6中类的用法,其实它只是一个语法糖。感谢Om Shakar以及Javascript Room中...

    xiao7cn 评论0 收藏0
  • JavaScript 深拷贝性能分析

    摘要:它接受任意数量的源对象,枚举它们的所有属性并分配给。所以现在怎么办有几种方法可以创建一个对象的深拷贝。为了防止发生任何意外,请使用而不是。我想测量哪种方法是最高性能的。图表以下是,和中不同技术的性能。 原文:Deep-copying in JavaScript - DasSur.ma 如何在 JavaScript 中拷贝一个对象?对于这个很简单的问题,但是答案却不简单。 引用传值 在...

    MyFaith 评论0 收藏0
  • Javascript的对象拷贝

    摘要:的对象只是指向内存中某个位置的指针。所以在拷贝中的对象时,要根据实际情况做一些考虑。结论中最好的对象拷贝的算法,很大程度上取决于其使用环境,以及你需要拷贝的对象类型。 翻译:疯狂的技术宅原文:https://smalldata.tech/blog/2... 本文首发微信公众号:前端先锋欢迎关注,每天都给你推送新鲜的前端技术文章 在开始之前,我先普及一些基础知识。Javascrip...

    simpleapples 评论0 收藏0
  • JS的深浅拷贝

    摘要:引用类型之所以会出现深浅拷贝的问题,实质上是由于对基本类型和引用类型的处理不同。另外方法可以视为数组对象的浅拷贝。上面描述过的复杂问题依然存在,可以说是最简陋但是日常工作够用的深拷贝方式。 一直想梳理下工作中经常会用到的深拷贝的内容,然而遍览了许多的文章,却发现对深拷贝并没有一个通用的完美实现方式。因为对深拷贝的定义不同,实现时的edge case过多,在深拷贝的时候会出现循环引用等问...

    xiaoxiaozi 评论0 收藏0
  • javascript设计模式与开发实践(二)- 封装和原型模式

    摘要:对象会记住它的原型给对象提供了一个名为的隐藏属性,某个对象的属性默认会指向它的构造器的原型对象,即。我们通过代码来验证再来实际上,就是对象跟对象构造器的原型联系起来的纽带切记这句话,对未来理解原型链很有帮助。 封装 封装数据 在许多语言的对象系统中,封装数据是由语法解析来实现的,这些语言也许提供了 private、public、protected 等关键字来提供不同的访问权限。例如:j...

    luxixing 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<