JavaScript中this指向以及改变this指向

关于this指向

  • 如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是
    window。
    var a="陇锦";
   function foo() {
     var a="掘金";
     console.log(this.a);
     console.log(this)
   };
   foo();
复制代码
  • 如果一个函数中有this,这个函数被上一级的对象所调用,那么this指向的就是上一级的对象。
    var a="陇锦";
    var foo = {
        a:"掘金",
        fn:function(){
            console.log(this.a); 
        }
    };
    foo.fn();
复制代码
  • 如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的
    var a={
        b:"陇锦",
        c:{
            // b:"掘金",
            fn:function() {
            console.log(this.b);//undefined
            }
        }
    };
    a.c.fn();
复制代码
  • this指向永远都是最后调用他的对象,可以对比一下前面的例子。这里q被赋值为fn函数,运行q,他的this就会改变。
    var a={
        b:"陇锦",
        c:{
            fn:function() {
            console.log(this.b);
            console.log(this);
            }
        }
    };
    var q=a.c.fn;
    q();
复制代码

当 this 碰到 return

  • 如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
        function fn() {
            this.b="陇锦";
            return {
                b:"掘金"
            };
        };
        var a=new fn;
        console.log(a.b);
复制代码
   function fn() {
               this.b="陇锦";
               function (){}
           };
           var a=new fn;
           console.log(a.b);
复制代码
  • 但需要注意的是,虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。
    function fn() {  
        this.b = '陇锦';  
        return null;
    }
    var a = new fn;  
    console.log(a.user); 
复制代码

如何改变this指向

  • 通过new:用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,
    那么this指向的自然是对象a,那么为什么对象a中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份.
    function Fn(){
        this.b = "掘金";
    }
    var a = new Fn();
    console.log(a.b);
复制代码
  • call方法和apply方法
    • 每个函数都包含两个非继承而来的方法:call()方法和apply()方法。
    • 相同点:这两个方法的作用是一样的。都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。
     window.color = 'red';
     document.color = 'yellow';
    
     var s1 = {color: 'blue' };
     function changeColor(){
         console.log(this.color);
     };
     changeColor.call();         //red (默认传递参数)
     changeColor.call(window);   //red
     changeColor.call(document); //yellow
     changeColor.call(this);     //red
     changeColor.call(s1);       //blue
复制代码
     window.number = 'one';
     document.number = 'two';
    
     var s1 = {number: 'three' };
     function changeColor(){
        console.log(this.number);
     };
     changeColor.apply();         //one (默认传参)
     changeColor.apply(window);   //one
     changeColor.apply(document); //two
     changeColor.apply(this);     //one
     changeColor.apply(s1);       //three
复制代码
  • 不同点:接收参数的方式不同
    • apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
      • 语法:apply([thisObj [,argArray] ]);,调用一个对象的一个方法,2另一个对象替换当前对象。
    • 说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。
    • call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。
      • 语法:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,应用某一对象的一个方法,用另一个对象替换当前对象。
      • 说明: call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新
        对象,如果没有提供thisObj参数,那么Global对象被用于thisObj。
 function add(c,d){
        return this.a + this.b + c + d;
    }

    var s = {a:1, b:2};
    console.log(add.call(s,3,4)); // 1+2+3+4 = 10
    console.log(add.apply(s,[5,6])); // 1+2+5+6 = 14 
复制代码
  • bind方法
    var a = {
        user:"掘金",
        fn:function(){
            console.log(this.user);
        }
    };
    var b = a.fn;
    b.bind(a);  //代码没有被打印
复制代码
  • 我们发现代码没有被打印,因为bind方法返回的是一个修改过后的函数。
    var a = {
        user:"掘金",
        fn:function(){
            console.log(this.user);
        }
    }
    var b = a.fn;
    var c = b.bind(a);
    console.log(c); //此时会吧函数打印出来
    
复制代码
  • 输出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);
复制代码
  • call和apply都是改变上下文中的this并立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在
    执行的时候添加,这是它们的区别

参考博客:追梦子blog http://www.cnblogs.com/pssp/

内容如有错误,欢迎指正。文章只写给需要的人,大牛忽略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值