共计 1348 个字符,预计需要花费 4 分钟才能阅读完成。
前提知识
在实现克隆函数之前, 你需要明白以下一些概念, 如果你已经明白了, 请直接阅读“实现”部分.
什么是值类型、引用类型?
很多新手可能会对“值类型”、“引用类型”、“原始类型”、“基本类型”等等名称感到困惑. 这里就解释一下这些概念.
一个事物是可以有多种区分形式的.
比如, 猫, 我们可以说它是猫科动物, 也可以说它是哺乳动物, 也可以说它是食肉动物.
在编程语言的世界里也是一样的.
在 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 TypeJavascript 之实现一个 clone 克隆函数 JavaScript: clone a functionFunction.prototype.bind()