一起手写吧!深拷贝!(未完成)

深拷贝和浅拷贝的主要区别,就是,其在内存中的存储类型不同。

堆和栈都是内存中划分出来用来存储的区域。

栈(stack)为自动分配的内存空间,它由系统自动释放;而堆(heap)则是动态分配的内存,大小不定也不会自动释放。

在将深拷贝和浅拷贝之前,我们先来重新回顾一下 ECMAScript 中的数据类型。主要分为

基本数据类型主要是:undefined,boolean,number,string,null。 

基本数据类型存放在栈中

存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问。

基本数据类型值不可变

javascript中的原始值(undefined、null、布尔值、数字和字符串)与对象(包括数组和函数)有着根本区别。
原始值是不可更改的:任何方法都无法更改(或“突变”)一个原始值。
对数字和布尔值来说显然如此,改变数字的值本身就说不通,而对字符串来说就不那么明显了,因为字符串看起来像由字符组成的数组,我们期望可以通过指定索引来假改字符串中的字符。
实际上,javascript 是禁止这样做的。字符串中所有的方法看上去返回了一个修改后的字符串,实际上返回的是一个新的字符串值。

基本数据类型的值是不可变的,动态修改了基本数据类型的值,它的原始值也是不会改变的,举一个例子~!

    var str = "abc";

    console.log(str[1]="f");    // f

    console.log(str);           // abc

不要以为 js 是一个灵活的语言,任何值应该都是可变的!

我们通常情况下都是对一个变量重新赋值,而不是改变基本数据类型的值。就如上述引用所说的那样,在 js 中没有方法是可以改变布尔值和数字的。倒是有很多操作字符串的方法,但是这些方法都是返回一个新的字符串,并没有改变其原有的数据。

所以,再次强调:基本数据类型值不可变

 

基本类型的比较是值的比较

基本类型的比较是值的比较,只要它们的值相等就认为他们是相等的,举个例子~!

    var a = 1;
    var b = 1;
    console.log(a === b);//true

比较的时候最好使用严格等,因为 == 是会进行类型转换的,看~

    var a = 1;
    var b = true;
    console.log(a == b);//true

说完了基本类型,我们继续往下~

 

引用类型存放在堆中

引用类型(object)是存放在堆内存中的,变量实际上是一个存放在栈内存的指针,这个指针指向堆内存中的地址。

每个空间大小不一样,要根据情况开进行特定的分配,来看个例子吧!

var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};

引用类型值可变

引用类型是可以直接改变其值的,例如:

    var a = [1,2,3];
    a[1] = 5;
    console.log(a[1]); // 5

引用类型的比较是引用的比较 

所以每次我们对 js 中的引用类型进行操作的时候,都是操作其对象的引用(保存在栈内存中的指针)。

所以比较两个引用类型,是看其的引用是否指向同一个对象。

来,看个例子~!

    var a = [1,2,3];
    var b = [1,2,3];
    console.log(a === b); // false

虽然变量 a 和变量 b 都是表示一个内容为 1,2,3 的数组,但是其在内存中的位置不一样,也就是说变量 a 和变量 b 指向的不是同一个对象,所以他们是不相等的。

传值与传址

了解了基本数据类型与引用类型的区别之后,我们就应该能明白传值与传址的区别了。
在我们进行赋值操作的时候,基本数据类型的赋值(=)是在内存中新开辟一段栈内存,然后再把再将值赋值到新的栈中。

如此这般:

var a = 10;
var b = a;
a ++ ;
console.log(a); // 11
console.log(b); // 10

 

基本类型的赋值的两个变量,是两个独立相互不影响的变量。

但是!引用类型的赋值是传址。只是改变指针的指向。

也就是说,引用类型的赋值是对象保存在栈中的地址的赋值,这样的话两个变量就指向同一个对象,因此两者之间操作互相有影响。来看代码~!

var a = {}; // a保存了一个空对象的实例
var b = a;  // a和b都指向了这个空对象

a.name = 'jozo';
console.log(a.name); // 'jozo'
console.log(b.name); // 'jozo'

b.age = 22;
console.log(b.age);// 22
console.log(a.age);// 22

console.log(a == b);// true

浅拷贝

当当当当!基础打完了,终于开始入题啦!

赋值和浅拷贝有什么区别呢,我们来看下面的例子:

    var obj1 = {
        'name' : 'zhangsan',
        'age' :  '18',
        'language' : [1,[2,3],[4,5]],
    };

    var obj2 = obj1;


    var obj3 = shallowCopy(obj1);
    function shallowCopy(src) {
        var dst = {};
        for (var prop in src) {
            if (src.hasOwnProperty(prop)) {
                dst[prop] = src[prop];
            }
        }
        return dst;
    }

    obj2.name = "lisi";
    obj3.age = "20";

    obj2.language[1] = ["二","三"];
    obj3.language[2] = ["四","五"];

    console.log(obj1);  
    //obj1 = {
    //    'name' : 'lisi',
    //    'age' :  '18',
    //    'language' : [1,["二","三"],["四","五"]],
    //};

    console.log(obj2);
    //obj2 = {
    //    'name' : 'lisi',
    //    'age' :  '18',
    //    'language' : [1,["二","三"],["四","五"]],
    //};

    console.log(obj3);
    //obj3 = {
    //    'name' : 'zhangsan',
    //    'age' :  '20',
    //    'language' : [1,["二","三"],["四","五"]],
    //};

猜你喜欢

转载自www.cnblogs.com/magicg/p/12664095.html