this

在多数情况下,函数的调用方式决定了this的值。this不能在执行期间被赋值,并且再每次函数被调用时this的值也可能会不同。

语法

this
当前执行代码的环境对象,在非严格模式下,总是指向一个对象,在严格模式下可以是任意值


全局环境

无论是否在严格模式下,在全局执行的环境中(在任何函数体外部)this都指向全局对象。

//在浏览器中,window对象同时也是全局对象:
console.log(this===window); // true
a=37;
console.log(window.a); // 37
this.b="MayDay";
console.log(wondow.b) //"MayDay"
console.log(b) //"MayDay"

你可以使用globalThis获取全局对象,无论你的代码是否在当前上下文运行。


函数(运行内)环境

在函数内部,this的值取决于函数被调用的方式。

简单调用

因为下面的代码不在严格模式下,且 this 的值不是由该调用设置的,所以 this 的值默认指向全局对象。

function f1(){
    return this;
}
//在浏览器中:   全局对象时window
f1()===window;  

然而,在严格模式下,this 将保持他进入执行环境时的值,所以下面的this将会默认为undefined。

function f2(){
    "use strict"; //这里是严格模式
    return this;
}
f2()=== undefined ;  //true

所以,在严格模式下,如果 this 没有被执行环境定义,那他将保持为undefined。

在第二个栗子中,this的确应该是undefined,因为f2是直接被调用的,而不是作为对象的属性或者方法调用的(如window.f2())。有一些浏览器最初在支持严格模式时没有正确实现这个功能,于是他们错误的返回了window对象。

如果要想把 this 的值从一个环境传到另一个环境,就用call或者apply方法。

//将一个对象作为call和apply的第一个参数,this会被绑定到这个对象。
var obj = { a : 'Custom'};
//这个属性事在global对象定义的。
var a = 'Global';

function whatThis(data){
      return this.a;   //this的值取决于函数的调用方式
}

whatThis();          //'Global'
whatThis.call(obj)       //'Custom'
whatThis.apply(obj)      //'Custom'

当一个函数在其主体中使用 this 关键字时,可以通过使用函数继承自Function.prototypecall或者apply方法将 this 值绑定到调用中的特定对象。

function add (c,d){
      return this.a + this.b + c + d;
}
var o = { a:1,b:3};

//第一个参数是作为 this 使用的对象 
//后续参数作为参数传递给函数调用
add.call(o,5,7);  // 1+3+5+7  = 16

//第一个参数是作为 this 使用的对象 
//第二个参数是一个数组,数组里的元素用作函数调用中的参数
add.apply(o,[10,20]); //1+3+10+20 = 34

使用call和apply函数时要注意,如果传递给this的值不是一个对象,js会尝试使用内部ToObject操作将其转换为对象。因此,如果传递的值是一个原始值比如7或者'foo',原始值会被转换成对象,像newNumber(7)这样,而字符串'foo'转化成 new String('foo') 这样,例如:

function bar(){
      console.log(Object.prototype.toString.call(this));
}
//原始值 7 被隐式转换成对象
bar.call(7)   //[Object Number]
bar.call('foo') //[Object String]
posted @ 2020-04-30 11:28  Lucyy  阅读(233)  评论(0编辑  收藏  举报