第11题 this指向问题

1 分析代码下面输出什么

    function Foo() {
      getName = function () {
        console.log(1);
      };
      return this;
    }
    Foo.getName = function () {
      console.log(2);
    };
    Foo.prototype.getName = function () {
      console.log(3);
    };
    var getName = function () {
      console.log(4);
    };
    function getName() {
      console.log(5);
    }
    Foo.getName();
    Foo().getName();
    getName();
    new Foo.getName();
    new Foo().getName();
    new new Foo().getName();
  1. Foo.getName();

调用Foo的静态方法,所以,打印2

  1. Foo().getName();

Foo()就是普通函数调用,返回的this是window,后面调用window.getName()window下的getName在Foo()中调用getName被重新赋值,所以,打印1

  1. getName();

在执行过Foo().getName()的基础上,所以getName=function(){console.log(1)},所以,打印1,[如果getName()放在Foo().getName()上执行打印结果为4]

  1. new Foo.getName();

构造器私有属性的getName(),所以,打印2

  1. new Foo().getName();

原型上的getName(),打印3

  1. new new Foo().getName()
  • 首先new Foo()得到一个空对象{}
  • 第二步向空对象中添加一个属性getName,值为一个函数
  • 第三步new {}.getName()
  • 等价于 var bar = new (new Foo().getName)(); console.log(bar)
  • new Foo得到的实例对象上的getName方法,再将这个原型上getName方法当做构造函数继续new ,所以执行原型上的方法,打印3

2 写出打印结果,并分析出原因

    var length = 10;
    function fn() {
      console.log(this.length);
    }
     
    var obj = {
      length: 5,
      method: function(fn) {
        fn();
        arguments[0]();
      }
    };
     
    obj.method(fn, 1);  
  • 解析:首先,我们在全局定义了一个变量length、一个对象obj和一个函数fnlength赋值为10。接下来是fn函数,输出this.length。对象obj中,obj.length是5,obj.method是一个函数。method函数里面的形参也是一个函数,这个函数里面调用了fn函数,arguments是一个伪数组,代表method函数实际接收到的参数列表,所以arguments[0] ()就代表了调用arguments里的第一项。obj.method(fn, 1)代表的就是调用obj当中的method函数,并且传递了两个参数,fn1
  • 分析完了代码的含义,我们来看输出结果。method函数当中调用的fn函数是全局当中的函数,所以this指向的是windowthis.length就是10。上面说了,arguments[0] ()代表的是调用arguments里面的第一项,也就是传参进来的fn,所以这个this指向的是arguments,method函数接收的参数是两个,所以arguments.length就是2。最后的输出结果就是 10 2

3 写出打印结果,并分析出原因

    function a(xx){
      this.x = xx;
      return this;
    };
    var x = a(5);
    var y = a(6);
    
    console.log(x.x);
    console.log(y.x);
  • 解析:首先,我们在全局定义了一个变量x、一个变量y和一个函数a,函数a当中的this.x等于接收到的参数,返回this,这里要注意,返回的不是this.x,而是this。接下来我们给x赋值,值为a(5),又给y进行赋值,值为a(6)。最后,我们输出x.xy.x
  • 分析完代码的含义,我们来看输出结果。a函数传了一个参数5,那么this.x就被赋值为了5,函数athis指向的是window,也就是window.x = 5。上面我们说过,这个函数返回的是this,也就是this指向的windowx = a(5)就相当于window.x = window,此时的x被赋值为了window。下面又执行了y = a(6),也就是说,x的值再次发生了改变,边为了6y则被赋值为了windowconsole.log(x.x)就相当于console.log(6.x),输出的自然是undefinedconsole.log(y.x),输出的相当于是console.log(window.x),得到的值自然是6。最后输出的结果为 undefined 6
Last Updated:
Contributors: leeguooooo