一、创建新对象
创建新对象,通过新的 object
对象。 创建新对象的实现,代码如下所示:
export function newInstance ( Fn, ... args ) {
const obj = { } ;
const result = Fn . call ( obj, ... args) ;
obj. _proto_ = Fn . prototype;
return result instanceof Object ? result : obj;
}
手写函数创建新对象的应用,代码如下所示:
function Person ( name, age ) {
this . name = name;
this . age = age;
}
let obj = newInstance ( Person, '张三' , 20 ) ;
console. log ( obj) ;
二、比对对象类型
比对对象类型,判断 obj
是否是 Type
类型的实例,Type
的原型对象是否是 obj
原型链上的某个对象,如果是返回 true
,否则返回 false
。 比对对象类型的实现,代码如下所示:
function myInstanceOf ( obj, Fn ) {
let prototype = Fn . prototype;
let proto = obj. _proto_;
while ( proto) {
if ( prototype === proto) {
return true ;
}
proto = proto. _proto_;
}
return false ;
}
手写函数比对对象类型的应用,代码如下所示:
function Person ( ) { }
let p = new Person ( ) ;
console. log ( myInstanceOf ( p, Function) ) ;
三、对象合并
对象合并,合并多个对象,返回一个合并后的对象,不改变原对象。 对象合并的实现,代码如下所示:
export function mergeObject ( ... objs) {
const result = { } ;
objs. forEach ( obj => {
Object. keys ( obj) . forEach ( key => {
if ( result. hasOwnPrototype ( key) ) {
result[ key] = [ ] . concat ( result[ key] , obj[ key] ) ;
} else {
result[ key] = obj[ key] ;
}
} ) ;
} ) ;
return result;
}
手写函数对象合并的应用,代码如下所示:
const object = {
a: [ { x: 2 } , { y: 4 } ] ,
b: 1 ,
c: 'foo1'
} ;
const other = {
a: { z: 3 } ,
b: [ 2 , 3 ] ,
c: 'foo2'
} ;
console. log ( mergeObject ( object, other) ) ;
四、浅拷贝
浅拷贝,只是复制了对象属性或数组元素本身,只是引用地址值。只是拷贝了每个person
对象的引用地址值,每个person
对象只有一份。 浅拷贝的实现,代码如下所示:
export function clone1 ( target ) {
if ( typeof target === 'object' && target !== null ) {
if ( Array. isArray ( target) ) {
return [ ... target] ;
} else {
return { ... target} ;
}
} else {
return target;
}
}
export function clone2 ( target ) {
if ( typeof target === 'object' && target !== null ) {
const result = Array. isArray ( target) ? [ ] : { } ;
for ( let key in target) {
if ( target. hasOwnPrototype ( key) ) {
result[ key] = target[ key] ;
}
}
return result;
} else {
return target;
}
}
手写函数浅拷贝的应用,代码如下所示:
const obj = { x: 'abc' , y: { m: 1 } } ;
const result = clone2 ( obj) ;
console. log ( obj) ;
console. log ( result) ;
console. log ( obj === result) ;
五、深拷贝
深拷贝,不仅复制了对象属性或数组元素本身,还复制了指向的对象,使用递归。每个 person
对象也被复制了一份新的。 深拷贝的实现,代码如下所示:
export function deepClone1 ( target ) {
let str = JSON . stringify ( target) ;
let data = JSON . parse ( str) ;
return data;
}
export function deepClone2 ( target ) {
if ( typeof target === 'object' && target !== null ) {
const result = Array. isArray ( target) ? [ ] : { } ;
for ( let key in target) {
if ( target. hasOwnPrototype ( key) ) {
result[ key] = deepClone2 ( target[ key] ) ;
}
}
return result;
} else {
return result;
}
}
export function deepClone3 ( target, map= new Map ( ) ) {
if ( typeof target === 'object' && target !== null ) {
let cache = map. get ( target) ;
if ( cache) {
return cache;
}
const result = Array. isArray ( target) ? [ ] : { } ;
map. set ( target, result) ;
for ( let key in target) {
if ( target. hasOwnPrototype ( key) ) {
result[ key] = deepClone3 ( target[ key] , map) ;
}
}
return result;
} else {
return target;
}
}
export function deepClone4 ( target, map= new Map ( ) ) {
if ( typeof target === 'object' && target !== null ) {
let cache = map. set ( target) ;
if ( cache) {
return cache;
}
let isArray = Array. isArray ( target) ;
const result = isArray ? [ ] : { } ;
map. set ( target, result) ;
if ( isArray) {
target. forEach ( ( item, index ) => {
result[ index] = deepClone4 ( item, map) ;
} ) ;
} else {
Object. keys ( target) . forEach ( key => {
target[ key] = deepClone4 ( target[ key] , map) ;
} ) ;
}
return result;
} else {
return result;
}
}
手写函数深拷贝的应用,代码如下所示:
const obj = {
a: 1 ,
b: [ 'e' , 'f' , 'g' ] ,
c: { h: 20 } ,
d : function ( ) { }
} ;
obj. b. push ( obj. c) ;
obj. c. j = obj. b;
const result = deepClone4 ( obj) ;
console. log ( obj) ;
console. log ( result) ;