this魔术背后的秘密

作为一个前端学习者,在学习之路上总会遇到一些难题,突发奇想,便随手记录一下。

关于this

this作为javascript常用的关键字之一,被人们称为最复杂的机制之一,他就像一个魔术师,变幻着令人着迷的戏法,来混淆你的视听。而作为观众的我们在欣赏完这眼花缭乱的魔术之后,总想了解一下背后的秘密。

理解this的指向

在js中,函数的几种调用方式有:
普通函数调用
作为对象方法来调用
作为构造函数来调用
使用apply/call方法来调用

this是在运行时进行绑定的,它的上下文取决于函数调用时的各种条件,this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
简单来说:this的最终指向的是那个调用它的对象(谁调用这个函数或者方法,this就指向谁)

普通函数调用
  function foo(){
    this.x = 1;
    console.log(this.x);
    console.log(this);
  }
  foo(); // 1   window

在这段代码中foo是直接使用了不带任何修饰的函数引用进行调用的,所以使用了默认绑定,即作为全局对象window的方法来进行调用的,可以看作window.foo();所以这里是window对象调用了foo这个方法,也就是说foo函数当中的this是指向window,同时window还具有了一个属性x,值为1。

var x = 1;
  function foo(){
    console.log(this.x);
  }
  foo(); // 1

这里为了证明this是全局变量,进行了一下小改变。一开始定义的全局变量x作为window的属性,在调用时,this肯定是指向全局对象window。

但是在严格模式下,则不能将全局对象用于默认绑定,因此this会绑定到undefined。

function foo(){
        "use strict";
    console.log(this.x);
  }
       var x = 1;
  foo(); // Uncaught TypeError: Cannot read property 'x' of undefined

虽然this的绑定规则完全取决于调用位置,但是只有foo()运行在非严格模式下时,默认绑定才能绑定到全局对象。

作为对象方法的调用
var obj = {
            x : "1",
            foo: function() {
              console.log(this.x);
            }
       };
  obj.foo(); // 1

这里的this指向的是对象obj,因为你调用这个foo是通过obj.foo()执行的,那this就指向就是对象obj。再次强调,this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式,谁调用的就指向谁,这个很重要。

作为构造函数来调用
function foo(){
      this.x = 1;
    }
    var obj = new foo();
    console.log(obj.x); // 1

这里可以实现输出1是因为new关键字可以改变this的指向,将this指向了obj对象。在传统的面向类语言中的new与js的new机制有着很多不同。在js中,构造函数只是使用new操作符时被调用的函数,不属于某个类,也不会实例化一个类,只是被new操作符调用的普通函数。new是可以影响函数调用时this绑定行为的方法,称之为new绑定。

使用apply/call方法来调用
function foo(){
      console.log(obj.x);
 }
  var obj = {
    x:2
  };
  foo.call(obj); // 2

通过foo.call(),调用foo时将this绑定在了obj上。从this绑定的角度上,call()和apply()是一样的。如果你把null或者undefined作为this绑定的对象传入call,apply或者bind,在调用时会被忽略,执行的是默认绑定规则。

最后

如果要判断一个运行中的函数的this指向,就需要找到这个函数直接调用的位置。即谁调用这个函数或者方法,this就指向谁。

this虽然只是js里的一小部分,对于我们学习者而言还是很重要的。this还有很多奥秘等着我们去发掘,我也只是知晓了其冰山一角,希望能分享一点自己的想法给一起学习路上的同学们,与君共勉。

参考

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值