zoukankan      html  css  js  c++  java
  • Javascript对象赋值操作

    首先,我们还是举个例子来说明对象赋值操作的问题吧:
    ps: 本文默认约定log = console.log

     function A(){}
     A.prototype.x = 10;
     var a1 = new A();
     A.prototype = {
     	x: 20,
     	y: 20
     };
     var a2 = new A();
    log([a1.x, a1.y, a2.x, a2.y]); // [10, undefined, 20, 20]
    

    js中对象赋值操作我们可以通过c语言中得指针概念来解释。

    对象的浅拷贝

    直接通过赋值操作符“=”将变量a中的对象赋值给变量b,此时我们更改a、b其中一个,另一个也会随之更改。

    var a = [1, 1],
    	b = a;
    	b[0] = 2;
    	log(a[0]); // 2
    

    因为我们在将a的对象赋值给b时,js引擎内部的操作只是简单的将a所指的对象的地址赋值给b,此时a与b指向内存中同一个对象,所以才会出现这种情况。这种赋值方式称为对象的浅拷贝。
    我们可以从另一个方面论证我们的观点:

    log(a === b); // true,毫无疑问
    
    var c = [2, 1];
    log(a === c); // false
    

    出现这种情况的原因就是变量c指向的是另一个和变量a指向的对象的值相同的对象,仅仅只是两个指向的对象的值相同,但两个对象在内存的地址是不一样的,所以是false。
    另外,我们知道js数组中有一些方法可以实现数组的完全复制,即两个变量分别指向两个对象:

    	b = a.concat([]),
        c = a.slice(0),
        d = a.splice(0, a.length);
    	log(b === a); // false
    

    但是我们要针对对象进行复制的话,只能手动进行模拟,即所谓的对象深拷贝。

    对象的深拷贝

    顾名思义,就是利用“=”对于基本类型的操作不存在上述问题,通过for-in深度遍历对象的属性,然后将其赋值给另一个新的对象。

    function cloneObj(obj) {
    	var tempObj = {};
    	
    	if (obj instanceof Array) {
    		tempObj = [];
    	}
    	
    	for (var prop in obj) {
    		if (typeof prop === 'Object') {
    			cloneObj(prop);
    		}
    		
    		tempObj[prop] = obj[prop];
    	}
    	
    	return tempObj;
    }
    
    var myCountry = {
    	name: 'China',
    	birth: 1949
    },
    
    country = cloneObj(myCountry);
    
    log(country === myCountry); // false
    

    结束语

    最后,我们回到第一个例子,会发现,引擎内部对于new对象的原型链也是通过简单的赋值操作的方式,即对象的浅拷贝。而ES5新增的Object.create()也是浅拷贝的一种封装:

    var myCountry = {
            name: 'China',
            birth: 1949
        },
    
        country = Object.create(myCountry);
    
    console.log(country.__proto__ === myCountry); // true
    
  • 相关阅读:
    从三道题目入门frida
    APP 抓包(应用层)
    安卓开发--探究碎片Fragment
    centos7-查询内存/硬盘等详细信息
    网页视频下载神器
    error: C++ preprocessor "/lib/cpp" fails sanity check错误解决方法
    make源文件时出现 /usr/bin/ld: cannot find -lstdc++ 错误
    安装docker后修改docker文件目录
    centos集群中各节点如何实现时间同步?
    redhat7.5 yum不能用
  • 原文地址:https://www.cnblogs.com/qingguo/p/5323815.html
Copyright © 2011-2022 走看看