发表于: 2017-05-22 21:36:04

2 1165


一,今天完成的事情
1.分页采用ui-bootstrap写的差不多了。
2.讲了一波小课堂,了解了深拷贝,浅拷贝,其实就是一句话:原始数据(string,number,null,undefined等),地址和具体内容都存在栈内存里面,引用数据(object,数组,函数)地址存在栈里面,具体内容存在堆里面。调用引用数据的时候其实就是一个指针,指向堆里面的同一个内存。深度复制只要复制到原始数据就好,数组可以用slice或者concat方法,对象自己写个迭代函数就好了,比如如下代码。
  function deepCopy(obj,c) {
    var c =c || {};
    for(var i in obj) {
      // 判断属性是否为对象,是的话就进一步展开
      if (typeof(obj[i]) === 'object') {
        // 递归拷贝
        if (obj[i].constructor == Array){
          c[i] = [];
          deepCopy(obj[i],c[i]);
        }
        else {
          c[i] = {};
          deepCopy(obj[i],c[i]);
        }
      }
      else {
        c[i] = obj[i];
      }
    }
    return c
  };
3.听了一波王帅的this指向,函数里面的this如果没有调用对象的话,这个this就会指向window(非严格模式下),严格模式下直接会返回undefined,下面的代码做个笔记。
var a=20;
var test;
obj= {
    a: 10,
    b:function() {
        console.log(this.a)
}
obj.b();//10,obj.b()中的this指向obj
test = obj.b;
test()//20,test中的this指向全局
二,明天预计完成的事情
完成分页,后台配置路由。
三.遇到的问题
四.收获

学到了深拷贝和浅拷贝的原理和实现方法,this指向相关。下面是PPT内容。



如何实现数组深拷贝和浅拷贝?

1.背景介绍

什么是栈内存和堆内存?

JavaScript中的变量的存放有有原始值与引用值之分,原始值代表了原始的数据类型,如Undefined,Null,Number, String,Boolean类型的值;而Object,Function,Array等类型的值便是引用值了。
栈内存中存放的是存储对象的地址,而堆内存中存放的是存储对象的具体内容。对于原始类型的值而言 ,其地址和具体内容都存在与栈内存中;而基于引用类型的值,其地址存在栈内存,其具体内容存在堆内存中。堆内存 与栈内存是有区别的,栈内存运行效率比堆内存高,空间相对堆内存来说较小,反之则是堆内存的特点。所以将构造简 单的原始类型值放在栈内存中,将构造复杂的引用类型值放在堆中而不影响栈的效率。

2.知识剖析

什么是深拷贝和浅拷贝?
浅拷贝:复制一份引用,所有引用对象都指向一份数据,并且都可以修改这份数据。
深拷贝(复杂):复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制。可以使用slice和concat方法。

SLICE和CONCAT使用方法

slice:
语法:arrayObject.slice(start,end)
该方法并不会修改数组,而是返回一个子数组。
start:必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
end:可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
concat:
语法:arrayObject.concat(arrayX,arrayX,......,arrayX)
返回一个新的数组。该数组是通过把所有 arrayX 参数添加到 arrayObject 中生成的。如果要进行 concat() 操作的参 数是数组,那么添加的是数组中的元素,而不是数组。
arrayX:必需。该参数可以是具体的值,也可以是数组对象。可以是任意多个。

3.常见问题

深拷贝和浅拷贝的运用环境。

4.解决方案

这个要看大家具体的应用,注意到数组带来的影响。

5.编码实战

浅拷贝的实现,例如:
var arr = ["One","Two","Three"]; 
var arrto = arr; arrto[1] = "test”; 
document.writeln("数组的原始值:" + arr + "<br>");//Export:数组的原始值:One,test,Three
document.writeln("数组的新值:" + arrto + "<br>");//Export:数组的新值:One,test,Three
深拷贝之slice:
  var num = ["One","Two","Three"];
    var newNum = num.slice(0);
    newNum[1] = "haha";
    document.writeln("数组的原始值:" + num + "<br>");//Export:数组的原始值:One,Two,Three
    document.writeln("数组的新值:" + newNum + "<br>");//Export:数组的新值:One,haha,Three
       
深拷贝之concat     
    var arr = new Array(3)
    arr[0] = "George"
    arr[1] = "John"
    arr[2] = "Thomas"
    var arr2 = new Array(3)
    arr2[0] = "James"
    arr2[1] = "Adrew"
    arr2[2] = "Martin"
    document.write(arr.concat(arr2))//输出:George,John,Thomas,James,Adrew,Martin;
       
           

6.扩展思考

对象的深拷贝
对象自己写个迭代函数就好了,只需copy到最底层的比如如下代码。
  function deepCopy(obj,c) {
    var c =c || {};
    for(var i in obj) {
      // 判断属性是否为对象,是的话就进一步展开
      if (typeof(obj[i]) === 'object') {
        // 递归拷贝
        if (obj[i].constructor == Array){
          c[i] = [];
          deepCopy(obj[i],c[i]);
        }
        else {
          c[i] = {};
          deepCopy(obj[i],c[i]);
        }
      }
      else {
        c[i] = obj[i];
      }
    }
    return c
  };
7.参考文献

参考二:原生js对象的浅拷贝和深拷贝的总结


8.更多讨论

有被浅拷贝坑过的经历吗?


鸣谢

感谢大家观看
BY : 彭勇 | 李维文 



返回列表 返回列表
评论

    分享到