JavaScript
中的this
this
为什么如此多变?node
this老是跟它的执行上下文有关,而在JavaScript总会有开辟新的执行上下文的东西,好比函数,因此,this才如此的变化。
执行环境对
JavaScript
中的this
有影响吗?浏览器
JavaScript是一门解释型语言,须要有一个执行环境去执行它,一般的执行环境是浏览器,还有node脚本,还有`REPL`(“读取-求值-输出”循环(Read-Eval-Print Loop,简称REPL))。 若是对REPL有兴趣的话,博客中的另外一篇文章介绍了`REPL`
this
默认指代谁?安全
在不一样的执行环境中,会指代不一样的对象
浏览器中:函数
> this // Window {top: Window, window: Window,... > this === window //true > var a = 1; //在全局中,用var声明变量,会默认给window添加 > this.a // 1 > window.a // 1 > b = 1; //不使用var声明变量,会默认给全局的this添加属性 > this.b // 1 > window.b // 1
在node
脚本中oop
console.log(this); //{} console.log(this === global); //false console.log(this === window); //ReferenceError: window is not defined var a = 1; //在全局中,使用var声明变量,未给global添加属性 console.log(this.a); //undefined console.log(global.a); //undefined console.log(window.a); //ReferenceError: window is not defined b = 1; //不使用var声明变量,会默认给全局的global添加属性。 console.log(this.b); //undefined console.log(global.b); // 1 在node脚本中,this默认指向一个空对象,并非指向global,也不是指向window。
在REPL
中this
> this { DTRACE_NET_SERVER_CONNECTION: [Function], DTRACE_NET_STREAM_END: [Function], ... > global === this //true > var a = 1; //在全局中,使用var声明变量,会默认给全局的global添加属性 > this.a // 1 > global.a // 1 > b = 1; //不使用var声明变量,会默认给全局的this添加属性 > this.b // 1 > global.b // 1
咱们对于省略
var
的变量声明方式,咱们总说它是不安全的,可是是合法的。code
为何不安全?对象
如上文所述:不使用var声明变量,会让变量默认的添加到了全局的this中,这有时候会莫名的给变量提高它的做用域,从而影响其余全局变量。
举个栗子:ip
var position = "outer"; //this.position = "outer" function test(){ position = "inner"; //this.position = "inner",在函数执行后,覆盖原先的值 console.log(this.position); } test();
咱们在外部定义了一个名为position
的全局变量,它会被默认添加到全局this的属性上。作用域
而后在咱们的test
函数中,又定义了一个同名的变量,可是注意,函数中的变量声明没有用var
。
由于咱们并无对函数实例化,因此this.position
的this
会默认指代全局。
而当咱们调用函数test
时,函数会生成一个执行上下文,而内部position
会将做用域从函数内部提高到全局,从而覆盖(污染)了外部全局定义的position
变量。
因此,在JavaScript
的严格模式中,是不容许省略var
来声明变量的。故在声明变量的时候,就顺手加上var
吧。
this
在不一样的执行环境中的默认指代var
声明变量致使“变量提高”现象的发生及预防