对JavaScript中this & 上下文的理解

context --> what the value of this is

1. 首先我们执行console.log(this);,即在全局作用域内输出this的值:

  • 在node环境下,输出{}

  • 在浏览器环境下,输出Window {....}

2. 接着我们看下面一段代码:

function foo() {
  console.log(this);
}
foo();
  • 在node环境下,输出Object [global] {...}

  • 在浏览器环境下,输出Window {...}

--> by default, a function runs within the scope of the object that it sits in.

因此上一段代码中的foo();等同于window.foo();

(when you create something in the root scope, it's a part of the window object

3. 接着看下面一段代码

var obj = {
  foo: function () {
    console.log(this);
    console.log(this === obj);
  }
};
obj.foo();

输出结果为

{ foo: [Function: foo] }
true

当函数是作为对象的属性存在并调用时,函数中的this指对象,否则thiswindowstrict模式下thisundefined


思考题:

1. 下面代码输出结果是什么

var name = 'red';

function a() {
  const name = 'white';
  console.log(this.name);
}

function d(i) {
  return i();
}

const b = {
  name: 'yellow',
  detail: function () {
    console.log(this.name);
  },
  hello: function () {
    return function () {
      console.log(this.name);
    }
  } 
};

var name = 'The Window';

var object = {
  name: 'My Object',
  getNameFunc: function () {
    var that = this;
    return function () {
      return that.name;
    };
  }
};

const c = b.detail;              // line 1
b.a = a;                         // line 2
const e = b.hello();             // line 3

a();                             // line 5
c();                             // line 6
b.a();                           // line 7
d(b.detail);                     // line 8
e();                             // line 9
object.getNameFunc()();          // line 10 

由标注的line1开始读:

  • line 1: --> 相当于创建一个全局作用域下的函数c,函数cb.detail指向同一个函数语句,即console.log(this.name);

  • line 2: --> 相当于给对象b添加一个新的属性a,属性a对应的值与函数a指向同一个函数语句,即const name = 'white'; console.log(this.name);,此时对象b为

{
  name: 'yellow',
  detail: [Function: detail],
  hello: [Function: hello],
  a: [Function: a]
}
  • line 3: --> 相当于创建一个全局作用域下的函数e,并将b.hello()的函数返回值function () {console.log(this.name);}赋给e

  • line 5: --> a()是在window对象下运行,全局作用域内最后一次给name赋值为'The Window',因此this.namewindow.name, 即'The Window'(node环境下输出undefined-->当输出一个对象中不存在的属性时,输出值为undefined

  • line 6: --> c()也是在window对象下运行,this同样指window,输出'The Window'(node环境下输出undefined

  • line 7: --> b.a();b对象下运行,this.nameb.name,输出'yellow'

  • line 8: --> 由于d是一个在全局作用域下定义的函数,因此将b.detail所指向的函数语句放在全局对象执行,this指window,输出'The Window'(node环境下输出undefined

  • line 9: --> 由于e是一个在全局作用域下定义的函数,this指window,输出'The Window'(node环境下输出undefined

  • line 10: --> 返回值为'My Object'(但不打印结果)。原因:由于在object对象下执行了var that = this;, 因此that === object,即函数返回值为object.name,即'My Object'

2. 下面代码输出结果是什么

myobject.func();

var myobject = {
  foo: 'bar',
  func: function () {
    var self = this;             // line 1
    console.log(this.foo);       // line 2
    console.log(self.foo);       // line 3
    (function (){                // line 4
      console.log(this.foo);     // line 5
      console.log(self.foo);     // line 6
    })();
    function f() {               // line 8
      console.log(this.foo);
    }
    f();                         // line 11
  }
}
  • line 1: --> thismyobject,因此self也指myobject

  • line 2: --> 打印myobject.foo,即打印'bar'

  • line 3: --> 打印myobject.foo,即打印'bar'

  • line 4: --> 该立即执行函数并不是作为特定对象的属性存在并调用

  • line 5: --> this.foo默认为window.foo,全局对象不存在foo这个属性,因此打印undefined

  • line 6: --> 打印self.foo即打印myobject.foo,即打印'bar'

  • line 8: --> 函数f并不是作为特定对象的属性存在并调用

  • line 11: --> this.foo默认为window.foo,全局对象不存在foo这个属性,因此打印undefined

3. 下面代码输出结果是什么?

var myobject = {
  foo: 'bar',
  func: (function () {
    var self = this;
    console.log(this.foo);
    console.log(self.foo);

    (function () {
      console.log(this.foo);
      console.log(self.foo);
    })();
    function f() {
      console.log(this.foo);
    }
    f();
  })()
};

(function () {...})()并不是作为特定对象的属性存在并调用, this.foo默认为window.foo,全局对象不存在foo这个属性,因此打印五个undefined

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。