We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
先回忆一下JavaScript中的数据类型:
数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和引用数据类型。
引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
赋值是将某一数值或对象赋给某个变量的过程,分为下面 2 部分:
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
浅拷贝使用场景:
Object.assign()
Array.prototype.slice()
Array.prototype.concat()
深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。
深拷贝使用场景:
JSON.parse(JSON.stringify(object))
undefined
symbol
new Date()
jQuery
extend()
lodash
cloneDeep()
实现一个 Object.assign 大致思路如下:
Object
assign
Object.defineProperty
{}
Object()
to
for..in
if (typeof Object.assign2 != 'function') { // Attention 1 //原生情况下挂载在 Object 上的属性是不可枚举的,但是直接在 Object 上挂载属性 a 之后是可枚举的,所以这里必须使用 Object.defineProperty Object.defineProperty(Object, "assign2", { value: function (target) { // JS 对于不可写的属性值的修改静默失败(silently failed),在严格模式下才会提示错误 'use strict'; if (target == null) { // Attention 2 throw new TypeError('Cannot convert undefined or null to object'); } // Attention 3 var to = Object(target); for (var index = 1; index < arguments.length; index++) { var nextSource = arguments[index]; if (nextSource != null) { // Attention 2 // Attention 4 // 使用 for..in 遍历对象 nextSource 获取属性值 // 此处会同时检查其原型链上的属性 for (var nextKey in nextSource) { // 有的对象可能没有连接到 Object.prototype 上(比如通过 Object.create(null) 来创建),这种情况下,使用 object.hasOwnProperty(..) 就会失败,因此用 call if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } } return to; }, // 默认值是 false,即 enumerable: false writable: true, configurable: true }); }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
数据类型
先回忆一下JavaScript中的数据类型:
数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和引用数据类型。
引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
赋值(Copy)
赋值是将某一数值或对象赋给某个变量的过程,分为下面 2 部分:
浅拷贝(Shallow Copy)
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
浅拷贝使用场景:
Object.assign()
Array.prototype.slice()
/Array.prototype.concat()
深拷贝(Deep Copy)
深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。
深拷贝使用场景:
JSON.parse(JSON.stringify(object))
该方法有以下几个问题:
undefined
symbol
new Date()
jQuery
中的extend()
,lodash
中的cloneDeep()
)三者的区别
手动实现
Object.assign()
实现一个 Object.assign 大致思路如下:
Object
是否支持该函数,如果不存在的话创建一个函数assign
,并使用Object.defineProperty
将该函数绑定到Object
上。{}
传递进去,但必须设置值)。Object()
转成对象,并保存为to
,最后返回这个对象to
。for..in
循环遍历出所有可枚举的自有属性。并复制给新的目标对象(使用 hasOwnProperty 获取自有属性,即非原型链上的属性)。参考资料
The text was updated successfully, but these errors were encountered: