간단 한 js 개체 복사

23604 단어 자바 script
머리말
javascript 의 대상 (Object) 은 다른 프로 그래 밍 언어의 대상 과 마찬가지 로 현실 생활 의 대상 (물체) 에 비 추어 이해 할 수 있 습 니 다.javascript 에서 대상 (물체) 의 개념 은 현실 생활 에서 실제 적 인 물체 에 따라 이해 할 수 있다.javascript 에서 한 대상 은 속성 과 유형 을 가 진 단독 실체 일 수 있 습 니 다.우 리 는 그것 을 컵 과 비교 해 보 았 다.하나의 컵 은 하나의 대상 (물체) 으로 속성 을 가지 고 있다.컵 은 색깔, 도안, 무게, 어떤 재질 로 구성 되 어 있 는 지 등등 이 있다.자 바스 크 립 트 대상 도 특징 을 정의 하 는 속성 이 있 습 니 다.
이상 의 정 의 는 MDN 에서 나 왔 습 니 다. 관심 이 있 는 사람 은 MDN 에서 js 대상 에 관 한 지식 을 더 많이 알 수 있 습 니 다. 이 글 은 json 대상 에 대한 복사 로 관련 된 내용 이 비교적 간단 합 니 다.원래 lodash 의 clone 함 수 를 실현 하 는 것 을 고려 했 지만 lodash 의 소스 코드 를 보 니 저 는 포기 하 였 습 니 다. lodash 에서 모든 js 대상 과 관련 된 복사, Map, Set 등 대상 과 관련 된 복사 입 니 다.실현 방식 은 배 울 만 한 가치 가 있 고 후기 에는 lodash 에서 _.clone 함수 의 해석 을 할 것 이다.
2. 복사 함수 구축
/**
 *               
 * @param value
 * @returns {Object} return clone result
 *
 * @Example
 * //return {a:1,b:2}
 * var obj={a:1,b:2}
 * clone(obj)
 */
function clone(value) {
    var result = {};
    for (key in value) {
        result[key] = value[key]
    }
    return result;
}

이것 은 가장 간단 한 복사 대상 의 함수 입 니 다. 이것 은 가장 간단 한 글자 양의 복사 만 완성 할 수 있 고 많은 단점 이 있 습 니 다. 예 를 들 어 우리 가 한 대상 에 들 어가 지 않 으 면 잘못 보고 할 것 입 니 다. 그 다음 에 우 리 는 이 함수 에 대해 최적화 할 것 입 니 다.
2.1 매개 변수 가 대상 인지 판단
/**
 *          , js          ,  ,type function       。
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 * @example
 *
 * _.isObject({});
 * // => true
 *
 * _.isObject(null);
 * // => false
 */
function isObject(value) {
    var type = typeof value;
    return value != null && (type == 'object' || type == 'function');
}

이렇게 해서 우 리 는 들 어 오 는 매개 변수 에 대해 대상 인지 아 닌 지 를 판단 했다. 우리 의 clone 함수 가 아래 와 같이 되 었 다.
function clone(value) {
    var result = {};
    if (!isObject(value)) {
        return value
    }
    for (key in value) {
        result[key] = value[key]
    }
    return result;
}

2.2 매 거 대상 의 모든 속성clone 함수 에서 우 리 는 for...in 로 대상 의 속성 을 매 거 하지만 ECMAScript 5 부터 세 가지 원생 방법 으로 대상 의 속성 을 열거 하거나 매 거 하 는 데 사용 합 니 다.
  • for... in 순환 이 방법 은 대상 과 원형 체인 에서 매 거 진 모든 속성 을 순서대로 방문 합 니 다.
  • Object. keys (o) 이 방법 은 대상 o 자체 에 포 함 된 모든 속성 이름 의 배열 을 되 돌려 줍 니 다.
  • Object. getOWn Property Names (o) 이 방법 은 대상 o 가 가지 고 있 는 모든 속성 (매 거 진 여부 와 상 관 없 이) 의 이름 을 포함 하 는 배열 을 되 돌려 줍 니 다.

  • 이상 은 MDN 에서 인용 되 었 습 니 다.
    본 고 는 json 대상 의 깊 은 복사 만 토론 하기 때문에 우 리 는 직접 for...in 를 사용 하면 된다. 만약 에 구조 함수 가 있 는 대상 에 대해 우 리 는 대상 의 원형 체인 을 통 해 새로운 대상 을 구성 해 야 한다.본 논문 의 대상 은 간단 한 var result={} 등가 var result=new Object() 이다. 만약 에 우리 가 Foo 라 는 대상 이 있다 면 우 리 는 이 대상 의 인 스 턴 스 를 복사 하고 싶다 면 복사 대상 에 대한 설명 은 var result=new Foo() 이다.
    /**
      *       ,            。  
      *              。
      *createObject         MDN  Object.create()    。
      */
    function clone(value) {
        var result = createObject(value);
        if (!isObject(value)) {
            return value
        }
        for (key in value) {
            result[key] = value[key]
        }
        return result;
    }
    

    이렇게 해서 우 리 는 구조 함수 대상 에 대한 복사 가 실현 되 었 다. 본 고 는 필요 하지 않 지만 제 이 슨 대상 의 구조 함수 가 바로 Object() 이기 때문에 여러 구조 함수 중의 하나 라 고 할 수 있 지만 다른 복사 의 실현 을 유추 할 수 있다.
    현재 우리 가 매 거 진 대상 의 속성, 즉 key 의 배열 을 얻 고 직접 for...in 로 실현 합 니 다.
    var objectProto = Object.prototype;
    var hasOwnProperty = objectProto.hasOwnProperty; //           。
    function getKeys(object){
        var result = [];
        for (key in object) {
            if (hasOwnProperty.call(object, key)) {
                result.push(key);
            }
        }
        return result
    };
    

    2.3, 모든 속성 을 옮 겨 다 니 며 복사 가능
    function clone(value) {
        var result={},
            keys = []
        if (!isObject(value)) {
            return value
        }
        keys = getKeys(value)
        for (var i = 0; i < keys.length; i++) {
            var prop = keys[i]
            result[prop] = value[prop]
        }
        return result;
    }
    

    이것 은 대상 에 대한 복사 본 을 간단하게 실현 하 였 으 나, 일반적으로 이것 만 으로 는 부족 하 다. 대상 은 등급 이 있 기 때문에 우 리 는 재 귀적 으로 이러한 대상 을 옮 겨 다 닐 수 있다.
    /**
      *                。           
      */
    function baseClone(value) {
        var result={},
            keys = []
        if (!isObject(value)) {
            return value
        }
        keys = getKeys(value)
        for (var i = 0; i < keys.length; i++) {
            var prop = keys[i]
            result[prop] = baseClone(value[prop])
        }
        return result;
    }
    function clone(value){
    	return baseClone(value)
    }
    

    2.4 대상 배열 의 지원
    일반적으로 우리 가 처리 하 는 데 이 터 는 기본적으로 목록 과 같은 것 이다. 다음 과 같다.
    [
    	{name:'zhangsan',age:23,parent:[
    		{name:'xiaoming',age:54},
    		{name:'xiaohong',age:53}
    	]},
    	{name:'lisi',age:23,parent:[
    		{name:'xiaoming',age:54},
    		{name:'xiaohong',age:53}
    	]}
    ]
    

    이러한 데 이 터 를 처리 하면 우리 의 복사 함 수 는 무력 합 니 다. 실용성 을 위해 서 우 리 는 대상 배열 의 복 제 를 고려 합 니 다.
    /**
      *        ,     ,
      */
    function copyArray(source,result){
    	var index = -1,
    		length = source.length
    
    	result || (result = Array(length))
    	while (++index < length) {
    		result[index] = baseClone(source[index])
    	}
    	return result;
    }
    
    /**
      *     isArray  
      */
    function isArray(value) {
        return value instanceof Array
    }
    
    function baseClone(value) {
        var result,
            keys = []
        if (!isObject(value)) {
            result=value
        }else if(isArray(value)){
    		result=[]
    		return copyArray(value,result)
    	}else{
    		result={}
    		keys = getKeys(value)
    		for (var i = 0; i < keys.length; i++) {
    			var prop = keys[i]
    			result[prop] = baseClone(value[prop])
    		}
    	}
        return result;
    }
    function clone(value){
    	return baseClone(value)
    }
    

    OK, 여기까지. 우 리 는 이미 완 성 했 습 니 다. 대상 의 깊 은 복사, 복 제 된 대상 은 완전히 새로운 대상 이 고 원래 대상 의 값 에 영향 을 주지 않 습 니 다.
    소결
    이것 이 바로 기본 적 인 대상 딥 복사 함수 입 니 다.
    참고
    Object - JavaScript | MDN lodash gitbub 전송 문

    좋은 웹페이지 즐겨찾기