当前位置: 首页 > news >正文

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

前提知识

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

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

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

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

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

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

在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()

相关文章:

  • [总结]Android系统体系结构
  • 给第三方使用接口的 URL 签名实现
  • JVM【第四回】:【对象访问】
  • Flask 教程 第一章:Hello, World!
  • Netty源码解析1-Buffer
  • SCCM 2012 R2实战系列之一:SQL安装
  • 【CuteJavaScript】Angular6入门项目(3.编写服务和引入RxJS)
  • ahjesus 让我的MVC web API支持JsonP跨域
  • 《剑指offer》分解让复杂问题更简单
  • 文件编码
  • 关于springcloud Gateway中的限流
  • 老婆!辛苦了
  • 精品思维导图,流程图模板分享
  • ubuntu制作本地源
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • CEF与代理
  • interface和setter,getter
  • js对象的深浅拷贝
  • leetcode386. Lexicographical Numbers
  • Mac转Windows的拯救指南
  • PAT A1050
  • Rancher-k8s加速安装文档
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • XML已死 ?
  • 不上全站https的网站你们就等着被恶心死吧
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 聊聊sentinel的DegradeSlot
  • 码农张的Bug人生 - 初来乍到
  • 盘点那些不知名却常用的 Git 操作
  • 线上 python http server profile 实践
  • 用jquery写贪吃蛇
  • 原生js练习题---第五课
  • Spring第一个helloWorld
  • $.ajax()参数及用法
  • (06)Hive——正则表达式
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (第一天)包装对象、作用域、创建对象
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (汇总)os模块以及shutil模块对文件的操作
  • (转)fock函数详解
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .net MVC中使用angularJs刷新页面数据列表
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .netcore 获取appsettings
  • .NET框架设计—常被忽视的C#设计技巧
  • .net中生成excel后调整宽度
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...