让我们分别看一下所有三种情况:
function myFunction()
{
var value = 0;
}
在这里,您要在函数的范围内声明一个变量。每次调用函数时,都会创建变量(并分配内存)。当函数返回时,变量超出范围 - 变量value
被标记并将被 GC'ed。不能从比此函数范围“更高”的范围访问范围...如果此函数在其范围内定义了一个函数,则该函数将有权访问该变量value
(查看闭包以获取更多详细信息)。底线:该变量仅在调用函数时存在,并且在函数返回后不存在。
function myFunction()
{
this.value = 0;
}
在这里,您定义的函数可以是构造函数、方法、事件处理程序或以上所有内容的组合。this
是一个引用,它将指向调用函数的上下文。此上下文是“临时”确定的,并且可能会有所不同:
myFunction();// global scope, this points to window
var anObject = {method: myFunction};
anObject.method();//called in the object's context, this points to object
console.log(abObject.value);//logs 0
var instance = new myFunction();//as constructor
console.log(instance.value);//logs 0
document.getElementById('anInputField').onclick = myFunction;//on click, value will be set to 0
在最后一种情况下:
function myFunction()
{
this.value = 0;
}
myFunction.value = 0;
如果你写这个不会有任何区别:
function myFunction()
{}
myFunction.value = 0;
因为,正如我上面解释的:this
引用函数调用时的任何上下文。事实上,这不一定是myFunction
:通常不会是:
var anObject = {method: myFunction};
myFunction.value = 101;//myFunction.value is changed
anObject.method();
console.log(anObject.value);//0 -> the function still sets the value property to 0
如果要访问该函数内部的函数属性,最简单的方法是像引用任何其他对象一样引用该函数:
function myFunction()
{
this.value = myFunction.value;
}
myFunction.value = 101;
警告:只是一个友好的警告:在不检查全局变量的情况下在函数
中使用不是很安全...如果在没有显式上下文的情况下调用函数,JS默认使用全局 ( ) 对象。这意味着将属性分配给碰巧指向的任何对象的每一行都将设置一个全局变量:this
window
this
function myFunction()
{
this.foo = 'bar';
}
myFunction();
console.log(window.foo);//logs bar EVIL GLOBAL
防止全局对象被全局变量弄乱的几种方法:
function mySafeFunction()
{
'use strict';//throws errors, check MDN
//this defaults to null, instead of window
impliedGlobal = 'Error';//doesn't work
this.onGlobal = 'Error';//null.property doesn't work
}
//same goes for constructors, but a more precise check can be used, too (and works on older browsers)
function SafeConstructor()
{
if (!(this instanceof SafeConstructor))
{//this doesn't point to SafeConstructor if new keyword wasn't used
throw new Error('Constructor wasn\'t called with new keyword');
//or "correct" the error:
return new SafeConstructor();
}
console.log(this);// will always point to the SafeConstructor object
}