克隆,深拷贝,浅拷贝

克隆/拷贝/复制

  • 它们是同个东西
  • 拷贝对象/克隆对象

浅拷贝

  • 只拷贝对象表层的属性,引用值还是指向同个地址
  • 修改引用值会相互影响
    var person1 = {
        name:'张三'
    }
    function clone(origin, target){
        var tar = target || {};
        for(var key in origin){
            if(origin.hasOwnProperty(key)){
                tar[key] = origin[key];
            }
        }
        return tar;
    }

深拷贝的常用方法:

1.原生递归遍历拷贝
2.用JSON对象转换的方法来拷贝, 缺点是不能拷贝方法。

    var str = JSON.stringfy(obj); 
    var obj2 = JSON.parse(str);

3.jQuery的方法

深拷贝实现

  • 向下递归拷贝,完全拷贝出一个新的对象
    var person1 = {
        name:'张三',
        children:{
            first:{
                name:'张小一',
                age:18  
            },
            second:{
                name:'张小二',
                age:17
            }
        }
    }
    //深拷贝思路:
    //首先遍历的时候剔除prototype上面的东西
    //然后判断每项是不是引用值
    //1. 用typeof判断,函数类型function可直接赋值
    //2. 剔除null原始值打印为object的bug
    //引用值下,判断是数组还是对象
    //如果下层还有引用对象,赋值target[key]为数组或对象,递归调用拷贝函数,直到都为原始值
    
    function deepClone(origin, target){
        var target = target || {},
            objStr = Object.prototype.toString,
            arrType = '[object Array]';
        for(var key in origin){
            if(origin.hasOwnProperty(key)){
                if(typeof(origin[key]) == 'object' && origin[key] != null){
									
                    if(objStr.call(origin[key]) === arrType){
                        target[key] = [];
                    }else{
                        target[key] = {};
                    }
                    deepClone(origin[key], target[key]);
										
                }else{
                    target[key] = origin[key];
                }
            }
        }
        return target;
    }
	var person2 = deepClone(person1);
	person2.children.third = {
		name:'张小三',
		age:16
	};
	console.log(person2);
	console.log(person1);

对象属性遍历,this, caller, callee

链式操作:
sche.wakeup().morning().noon().afternoon();
实现:每个方法的最后 return this。

对象属性遍历:
obj.name //用.语法语法访问obj //实际上js引擎还是会给转成obj[‘name’]的形式,再访问
obj[‘name’] //用中括号可访问对象,属性名用字符串’’ //最早的JS引擎都是括号形式访问
字符串拼接的方式访问对象
obj[‘No’ + num] //访问形如No1, No2, No3此类的内容;

对象枚举方法:
数组遍历: for循环方法 //for(var i = 0; i < arr.length; i++){arr[i]}
(数组用for in 方法也可以)
对象遍历: for in 方法 //for(var key in obj){car[key]}
(for in 方法会遍历出原型链上的所有自定义属性,)

为什么for in里面,car.key访问不到?
car.key -> car[‘key’] -> 这个东西找不着,所以会返回undefined

判断是否是对象自身属性:只打印对象自身属性,排除原型链上属性的方法。一般使用obj.hasOwnProperty(key)来判断。

obj.hasOwnProperty(key) //方法返回true或false,放在if(xx)里面判断,返回true为自身的属性,才打印。

‘displacement’ in car
//返回true或false,隐式地找car[‘displacement’]存不存在
//前面一定要字符串括起来,直接写会报错

A instanceof B //判断A是否是B构造出来的

  // 访问对象不存在的属性,返回的是undefiend
  // 数组是特殊的对象,数组和对象都是引用值;

  // 枚举就是有一组有共同特性的数据,就是枚举;在js中实际是对象
  // 枚举 -> 遍历;遍历就是按顺序一个个获取信息的过程;
  // JavaScript中,有枚举就一定有遍历;

三种判断数组的方法:
Object.prototype.toString.call(arr); //尽可能用这种方法判断
arr instanceof Array //是否数组构造方法构造出来的 //会有一些小问题
arr.constructor
微信qq等第三方接口返回错误信息的方式
完整的AO
this指向问题
//全局this指向window
//预编译函数this -> window //普通函数(没有return this的过程)
//apply/call改变了this的指向
//构造函数的this指向实例化对象
构造函数的AO
call/apply
callee/caller
arguments.callee - 返回当前函数本身 //返回正在执行的函数本身,在哪个函数里面返回哪个函数 // 它是实参列表上的一个属性
test2.caller - 返回调用当前函数的函数 //返回调用了test2的那个函数的函数体,这两个严格模式下会报错
立即执行函数调用自身 - arguments.callee
函数本身的属性.length - 形参长度
– 例子:用递归的方式累加n
笔试题
默认传参
bar.call() -> bar() -> bar.call(arguments) -> bar(arguments);
JS的typeof能够返回哪些值
number, boolean, string, object(null), undefined, function

NaN考题
NaN == NaN ?
写一个判断NaN的函数, 实现isNaN的功能;
  判断那里要转为 res == 'NaN'
{} == {}? 为什么? 怎么相等?
  不等于; 因为引用值对比的是地址;
  引用值赋值,obj1 = obj;

浅拷贝,深拷贝,对象克隆,三目运算:

模块化开发作业
(团队协作开发)

模块化开发
  window.onload = fucntion(){
    init();
  }
  function init(){
    initFb();
  }
  var initFb = (function(){
    // 模块化 - 普通函数, return fun,initFb, init, onload,模块化直接用
    function fb(n){
      if(n <= 0){
        return 0;
      }
      if(n <= 2){
        return 1;
      }
      return fb(n - 1) + fb(n - 2);
    }
    return fb;
  })();

插件开发
  ;(function(){
    // 插件化 - 自启动,构造函数,原型,window, 插件要new一下用的
    var Fb = function(){}
    Fb.prototype.fb = function(n){
      if(n <= 0){
        return 0;
      }
      if(n <= 2){
        return 1;
      }
      return arguments.callee(n - 1) + arguments.callee(n -2);
    }
    window抛出去
    
  })();

三目运算
  ? :   //每种语言都有
三种写法
  一般: 
      a > 0 ? console.log('大于0')  //;x 三目运算是一条语句,中间不能加分号
            : console.log('小于0');
  return写法: 
      str = a > 0 ? '大于0'   //三目运算带有return 功能的
                  :'小于0';  //return
  嵌套写法:
      str = a > 0 ? (
                      a > 3 ? '大于3'
                            : '小于等于3'
                    )
                  : '小于等于0';
引用值的克隆/拷贝/复制  --真正的说法是叫克隆clone
  指向同个存储空间的克隆  //引用值
    var person1 = {name:'张三'};
    var person2 = person1;    //p1把存储地址的值给了p2,两者指向的是同个存储空间
    person2.name = '李四';
    // person1的值也会变成李四,因为
浅拷贝  //拷贝两个独立的对象,第一层属性互不影响
        //但如果属性里有引用值,那么修改时还是会相互影响;
  var person1 = {name:'张三'};
  var person2 = {}
  for(var key in person1){
    person2[key] = person1[key];
  }
  //此时修改p2的属性值,p1不变;因为二者是不同的对象,只是把一层的属性和值拷贝以一份;
写个浅拷贝函数; -- 53min
  
深拷贝
写个深拷贝函数
  function deepClone(origin, target){
    var tar = target || {},     //做一下用户体验
        toStr = Object.prototype.toString,
        arrType = '[object Array]';
    for(var key in origin){
      if(origin.hasOwnProperty(key)){
        if
      }
    }
  }

用JSON方法来深拷贝,
  缺点是不能拷贝方法
  var p1 = {name:'张三'}  
  var str = JSON.stringify(p1); //先转成JSON字符串
  var p2 = JSON.parse(str); //再把JSON字符串转成json对象
深拷贝有哪几种方法? - 3种
  JQ深拷贝方法
  JS原生递归的方法
  JSON的方法

作业:(把答案写出来,并写上是什么原因)
  function Foo(){
    getName = function(){
      console.log(1);
    }
    return this;
  }
  Foo.getName = function(){
    console.log(2);
  }
  Foo.prototype.getName = function(){
    console.log(3);
  }
  var getName = function(){
    console.log(4);
  }
  function getName(){
    console.log(5);
  }

  Foo.getName();
  getName();
  Foo().getName();
  new Foo.getName();
  new Foo().getName();
  new new Foo().getName();

测试题:
用prompt接受用户输入年份
判断是否是闰年? 用三目运算来做;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值