码迷,mamicode.com
首页 > Web开发 > 详细

js this指向

时间:2018-10-23 15:40:12      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:str   fine   引用   为什么   默认   col   上下文   app   代码   

this 是运行时到某个对象的绑定

1.隐式绑定

一般地,被直接对象所包含的函数调用时,也称为方法调用,this隐式绑定到该直接对象。

        function printA(){
          console.log(this.a)
        }
        var obj={
          a:616,
          print:printA
        }
        obj.print();   //616

使用 obj.print()来调用 obj 中的 print方法。这时候  printA() 处于被 obj 调用的上下文,故此时 this 被绑定到了 obj。这种根据被调用情况将 this绑定到对应对象上的情况我们称之为 隐式绑定。而称之为隐式绑定的原因则是,我们是在一个对象(上例中为 obj)内包含一个指向函数的属性(上例中的 obj.print),并通过这个属性间接(隐式)引用函数。

      function printA() {
          console.log(this.a);
      }
      var obj = {
          a: 616, print: printA
      };

      var alias = obj.print;
      alias(); // 输出为 undefined

      function callFunc(fn) {
          fn();
      }
      callFunc(obj.print); // 输出为 undefined 

这个例子中我们把 obj.print 赋值给了 alias ,本意为给 obj.print 起的别名,却发现结果得到了 undefined 。实际上,obj.print 持有的只是对 printA() 的引用而已,而 alias 也自然实际是指向 printA() 了。此时 alias() 显然不是由 obj 调用的,故并不能遵循隐式绑定的规则。至于 callFunc() ,我们传递进来的 obj.print 实际也是 printA() ,故它也不是被 obj 调用的,所以结果也是 undefined 了。

全局环境中,this默认绑定到window

2.显式绑定

callapplybindFunction对象自带的三个方法,都是为了改变函数体内部 this 的指向。

apply 、 call 、bind 三者第一个参数都是 this 要指向的对象,也就是想指定的上下文;apply 、 call 、bind 三者都可以利用后续参数传参;

 

将上面例子改成:

      function printA() {
          console.log(this.a);
      }
      var obj = {
          a: 616, print: printA
      };
      // var alias = obj.print;
      // alias(); // 输出为 undefined
      var alias=printA.bind(obj);
      alias()               //输出616

 

bind 是返回对应 函数,便于稍后调用;apply 、call 则是立即调用 。

var obj = {
  x: 81,
};
  
var foo = {
  getX: function() {
    return this.x;
  }
}
console.log(foo.getX.bind(obj)());  //81   bind返回的是函数 需要后面加()来调用
console.log(foo.getX.call(obj));    //81   call 立即调用
console.log(foo.getX.apply(obj));   //81  apply

call方法的原理:首先寻找call方法,最后通过原型链在Function的原型中找到call方法,然后让call方法执行,在执行call方法的时候,让fn方法中的this变为第一个参数值obj,最后再把fn这个函数执行。

function fn1() {
    console.log(1);
}
function fn2() {
    console.log(2);
}
fn1.call(fn2); // 1

首先fn1通过原型链查找机制找到Function.prototype上的call方法,并且让call方法执行,此时call这个方法中的this就是要操作的fn1。在call方法代码执行的过程过程中,首先让fn1中的“this关键字”变为fn2,然后再让fn1这个方法执行。

注意:在执行call方法的时候,fn1中的this的确会变为fn2,但是在fn1的方法体中输出的内容中并没有涉及到任何和this相关的内容,所以还是输出1.

对于 apply、call 二者而言,作用完全一样,只是接受 参数 的方式不太一样。call 是把参数按顺序传递进去,而 apply 则是把参数放在数组 里。

      var a={
        user:‘zhujianxiong‘,
        fn:function(e,ee){
          console.log(this.user);
          console.log(e+ee);
        }
      }
      var b=a.fn;                  //打印结果都是
      b.call(a,1,2);               //zhujianxiong  
      b.apply(a,[1,2]);            //3

注意如果call和apply的第一个参数写的是null,那么this指向的是window对象。

3.new绑定

使用 new 来调用构造函数(或者说,发生构造调用时),所执行的操作实际是这些:

  1. 创建一个全新的对象(这是为什么我们称之为 “构造函数” 或 “构造调用”)
  2. 对这个新对象执行 [[Prototype]] 链接(不再本次讨论范围内)
  3. 将新对象绑定到 this 
  4. 将这个新对象作为 new 表达式的返回值(如果函数没有返回其它对象的话)

 

 

js this指向

标签:str   fine   引用   为什么   默认   col   上下文   app   代码   

原文地址:https://www.cnblogs.com/zjx304/p/9836801.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!