关于This指向,改变指向, 深浅拷贝的几种方法

关于This, 深浅拷贝的几种方法

this指向问题

  1. this出现在构造函数中,指向构造函数新创建的对象
  2. this出现在函数中,那个对象调用,就指向调用者。
  3. this出现在全局函数中 永远指向window
  4. this出现在严格模式中 永远不会指向window
  5. this出现在原型函数中 参考2
  6. this出现在箭头函数中 定义时的环境(父级对象)

修改this指向的三种方式

  1. Function.prototype.call()
var a = {
    user:"苏苏苏",
    fn:function(){
        console.log(this.user); //苏苏苏
    }
}
var b = a.fn;
b.call(a);  //若不用call,则b()执行后this指的是Window对象

//  解释一下:把b添加到第一个参数的环境中,简单来说,this就会指向那个对象。

call方法除了第一个参数以外还可以添加多个参数,如下:

var a = {
    user:"苏苏苏",
    fn:function(e,ee){
        console.log(this.user); //苏苏苏
        console.log(e+ee); //3
    }
}
var b = a.fn;
b.call(a,1,2);
  1. Function.prototype.apply()
var a = {
    user:"苏苏苏",
    fn:function(){
        console.log(this.user); //苏苏苏
    }
}
var b = a.fn;
b.apply(a);

apply方法和call方法有些相似,它也可以改变this的指向,也可以有多个参数,但是不同的是,第二个参数必须是一个数组,如下:

var a = {
    user:"苏苏苏",
    fn:function(e,ee){
        console.log(this.user); //苏苏苏
        console.log(e+ee); //11
    }
}
var b = a.fn;
b.apply(a,[10,1]);

//注意如果call和apply的第一个参数写的是null,那么this指向的是window对象
var a = {
    user:"苏苏苏",
    fn:function(){
        console.log(this); //Window {external: Object, chrome: Object, document: document, a: Object, speechSynthesis: SpeechSynthesis…}
    }
}
var b = a.fn;
b.apply(null);
  1. Function.prototype.bind() es5

    bind方法和call、apply方法有些不同,如下:

    var a = {
    user:"苏苏苏",
    fn:function(){
        console.log(this.user);
    }
}
var b = a.fn;
b.bind(a);  //代码没有被打印

//我们发现代码没有被打印,对,这就是bind和call、apply方法的不同,实际上bind方法返回的是一个修改过后的函数

var a = {
    user:"苏苏苏",
    fn:function(){
        console.log(this.user);
    }
}
var b = a.fn;
var c = b.bind(a);
console.log(c); //function() { [native code] }

//函数c看看,能不能打印出对象a里面的user

var a = {
    user:"苏苏苏",
    fn:function(){
        console.log(this.user); //苏苏苏
    }
}
var b = a.fn;
var c = b.bind(a);
c();

// 同样bind也可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。

var a = {
    user:"苏苏苏",
    fn:function(e,d,f){
        console.log(this.user); //苏苏苏
        console.log(e,d,f); //10 1 2
    }
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);
  1. new关键字改变this指向
//构造函数版this
function Fn(){
    this.user = "苏苏苏";
}
var a = new Fn();
console.log(a.user); //苏苏苏

//原因:
用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象a中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份

深浅拷贝的几种方法

浅拷贝
var obj = {
            x: 1,
            y: [1, 2, 3, 5]
        }

        // var obj2 = obj; //对象赋值的是地址
        // obj2.x = 0;
        // console.log(obj);

        // 浅拷贝
        var obj2 = {};
        for (var item in obj) {
            obj2[item] = obj[item];
        }

        obj2.y[0] = 'aaa';
        console.log(obj2);
        console.log(obj);
使用JSON.parse 和 JSON.stringify 进行深拷贝
var obj = {
            x: 1,
            y: [1, 2, 3, 5]
        }

        // 使用JSON.parse 和 JSON.stringify 进行深拷贝
        var obj2 = JSON.parse(JSON.stringify(obj));
        obj2.y[0] = 'aaa';
        console.log(obj2);
        console.log(obj);
// 深拷贝 - > 浅拷贝
var obj = {
            x: 1,
            y: {
                a: 0,
                b: true,
                c: [1, 2, 3, 5]
            }
        };

        var obj2 = deepCopy(obj);
        console.log(obj2);
        // 深拷贝 - > 浅拷贝

        function getType(obj) {
            return Object.prototype.toString.call(obj).slice(8, -1);
        }

        // function deepCopy(obj) {
        //     var result, oClass = getType(obj); //获取数据类型
        //     if (oClass === "Object") { // 类型判断
        //         result = {};
        //     } else if (oClass === "Array") {
        //         result = [];
        //     } else {
        //         return obj; //值类型  不会执行下面的for - in 直接返回该值
        //     }
        //     for (var i in obj) {
        //         var copy = obj[i]; // 获取对象的每一个值
        //         if (getType(copy) === 'Object') {
        //             result[i] = deepCopy(copy);
        //         } else if (getType(copy) === 'Array') {
        //             result[i] = deepCopy(copy);
        //         } else {
        //             result[i] = copy;
        //         }
        //     }
        //     return result;
        // }

        function deepCopy(obj) {
            var result, oClass = getType(obj);
            if (oClass === 'Object') result = {};
            else if (oClass === 'Array') result = [];
            else return obj;
            for (var i in obj) {
                var copy = obj[i];
                if (getType(copy) === "Object" || getType(copy) === "Array") result[i] = arguments.callee(copy);
                else result[i] = copy;
            }
            return result;
        }
利用create方法
var obj = {
            x: 1,
            y: {
                a: 0,
                b: true,
                c: [1, 2, 3, 5]
            }
        };

        var obj2 = Object.create(obj);
        console.log(obj2);
利用jQuery里面的extend但是不能超过两层的拷贝
 var obj = {
            x: 1,
            y: {
                a: 0,
                b: true,
                c: [1, 2, 3, 5]
            }
        };
        var obj2 = $.extend({}, obj);
        console.log(obj2);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值