一句话理解javascript中的this指向

this默认指向方法所属的对象,当然你可以任意指定一个函数的this。

  this所属的对象,其实就是这个方法所处的一个上下文环境。怎么理解上下文这个东西,举个例子,你去自助餐厅吃饭,当你发生吃饭这个动作时,这个自助餐厅就赋予你一个上下文环境,你想吃什么,只要这里有,你就能随便吃,上下文环境为你提供一个拿来即用的环境,这个环境在js中通常就是一个对象。

//举例,想想以下问题:
function foo(a,b){
   this.a = a;
   this.b = b;
}
  想想当执行foo函数时,this代表了谁。

  如果只在script标签内书写了这么一段代码,我们知道foo是属于window对象的,那这里的this指的当然就是windows对象;当你执行foo(1,2)时你会发现window对象对了a、b两个属性。

  这里的this就是foo所属的对象obj ,当foo执行后,给obj添加了两个属性。此时obj就是你的上下文,他可以任意获取obj内的任意元素。

//再如:
var obj = {
    foo: function(a, b) {
        this.a = a;
        this.b = b;
    },
    num: 3
}
obj.foo(2, 3);
console.log(obj);

//你会发现输出:
{ foo: [Function: foo], num: 3, a: 2, b: 3 }

  这里的this就是foo所属的对象obj ,当foo执行后,给obj添加了两个属性。此时obj就是你的上下文,他可以任意获取obj内的任意元素。

  甚至我们可以这样写:
  function foo() {}
  foo.bar = function(a, b) {
      this.a = a;
      this.b = b;
  }
  foo.bar(2, 3)
  console.log(foo);
  //输出结果:
  { [Function: foo] bar: [Function], a: 2, b: 3 }
  //我们发现foo多了两个属性
  我们还可以这样使用

  所以方法所在的对象,就是它的上下文,他能提取这个所在对象的任意元素,也就是this的指向。

  var fnArr = [];
  fnArr.push(function() {
      this.push(3);
      this.push(4);

  })
  fnArr[0]();
  console.log(fnArr)
  //输出结果:
  [ [Function], 3, 4 ]
//我们发现数组多了两个元素,此时整个数组就是他的上下文环境,他可以通过this任意获取数组里边的元素,或者操作这个数组。

  所以方法所在的对象,就是它的上下文,他能提取这个所在对象的任意元素,或者操作这个对象,这个对象就是this的指向。重要的事情说三遍。

  到这里,可能有些人会提出使用new 关键字时的this指向问题。

  function Foo(a,b){
      this.a = a;
      this.b = b;
  }

  如果你不去new 这个实例,此时的this就指代window对象,应为在非严格模式下的浏览器环境下这个函数理所当然属于window,他当然可以从window这个上下文随意获取元素,这个问题,我们之前已经探讨过了。

  你可以这样写代码:

  function a(){ this.alert(1)}
  当然没人会这么写,应为此时的this或者Window是可以省略的,但是你不能否认即使是最简单的alert方法也是你从上下文中获取的。

  回到之前的;

  如果直接执行这个类(其实就是个函数)
  var foo = Foo(2,3); 此时的foo是undefined,应为函数压根没有返回值,而window却多了两个属性。

  我们通常这样去new一个实例:

  var foo = new Foo(2,3);
  先看看new干了什么,我们模拟一个mynew方法:

 function A(a, b) {
      this.a = a;
      this.b = b;
  }

  function myNew(fn, ...args) {
      let obj = {};
      obj.__proto__ = fn.prototype;
      fn.call(obj, ...args);
      return obj;
  }

  let a = myNew(A, 2, 3);

  此时的a对象和new出来的a对象是一样的。new一个对象时,首先构造了一个空对象,再将对象的__proto__指向函数(类就是个函数)的原型,最后执行函数再将this绑定在obj上,这样就形成了一个函数的实例。
说到这里我们就引出了任意绑定this的概念。

举个例子:

  你家的孩子要搭积木,你这里有好多包积木玩具,你一般会拿一包给他,当然你也能拿任意多包给他,此时放在他面前的积木就是他搭积木这个动作的上下文,他想拿方块拿方块,想拿三角拿三角。这个上下文就是你赋予他的,可以是任意品牌的积木。

  反映在js中,我们可以指定任意新的对象作为this的指向,而此时需要使用bind,call,apply三个方法;

bind用于绑定一个this:、

  当此函数执行时,this就是bind函数的参数,如 foo.bind({a:1,b:2}),之后foo执行的时候this就是{a:1,b:2},bind内的参数可以使任意的对象,当然它可以是一个变量。

call和apply会直接绑定this并执行:

  call(this对象,参数一,参数二,…) apply(this新对象,[参数一,参数二]),这两个方法第一个都是新的this对象,从第二个参数开始,call以多个参数形式传参,apply以数组形式传参,区别仅此而已。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值