当前位置: 首页 > 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工具测试有返回值)
  • 【Leetcode】104. 二叉树的最大深度
  • 77. Combinations
  • angular学习第一篇-----环境搭建
  • bearychat的java client
  • Fastjson的基本使用方法大全
  • hadoop集群管理系统搭建规划说明
  • HTTP那些事
  • java8-模拟hadoop
  • Java到底能干嘛?
  • Java深入 - 深入理解Java集合
  • js数组之filter
  • LeetCode29.两数相除 JavaScript
  • nginx 配置多 域名 + 多 https
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • ubuntu 下nginx安装 并支持https协议
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 机器学习中为什么要做归一化normalization
  • 前端存储 - localStorage
  • 数据科学 第 3 章 11 字符串处理
  • 物联网链路协议
  • 一个完整Java Web项目背后的密码
  • 正则表达式
  • ​iOS实时查看App运行日志
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #pragam once 和 #ifndef 预编译头
  • (02)Hive SQL编译成MapReduce任务的过程
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (Python) SOAP Web Service (HTTP POST)
  • (solr系列:一)使用tomcat部署solr服务
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)计算机毕业设计高校学生选课系统
  • (六)c52学习之旅-独立按键
  • (未解决)macOS matplotlib 中文是方框
  • (一)WLAN定义和基本架构转
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)