我正在努力理解javascript中的函数和对象.据说,函数也是对象,对象是一种"关联数组",即键值对的集合.我明白,如果我写
function myFunction() {
var value = 0;
}
alert(myFunction.value); //then this gives me "undefined"
Run Code Online (Sandbox Code Playgroud)
因为变量有功能范围.但如果我写
function myFunction() {
this.value = 0;
}
alert(myFunction.value); //then this gives me "undefined" too.
Run Code Online (Sandbox Code Playgroud)
但最后,如果我写
function myFunction() {
this.value = 0;
}
myFunction.value = 0;
alert(myFunction.value); //then this gives me 0
Run Code Online (Sandbox Code Playgroud)
所以我可以给myFunction属性"value"但是来自"outside".有人可以解释发生了什么以及为什么this.value = 0; 不会创造属性"价值".
Eli*_*gem 13
让我们分别看看这三种情况:
function myFunction()
{
var value = 0;
}
Run Code Online (Sandbox Code Playgroud)
在这里,您在函数的范围内声明了一个变量.每次调用该函数时,都将创建该变量(并将分配内存).当函数返回时,变量超出范围 - 变量value被标记并将被GC.无法从比此函数范围"更高"的范围访问范围...如果此函数在其范围内定义了一个函数,则该函数将可以访问该变量value(查看闭包以获取更多详细信息).底线:变量仅在调用函数时存在,并且在函数返回后不存在.
function myFunction()
{
this.value = 0;
}
Run Code Online (Sandbox Code Playgroud)
在这里,您定义的函数可以是构造函数,方法,事件处理程序或上述所有组合.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
Run Code Online (Sandbox Code Playgroud)
在最后一种情况下:
function myFunction()
{
this.value = 0;
}
myFunction.value = 0;
Run Code Online (Sandbox Code Playgroud)
如果你写完这篇文章就没有任何区别:
function myFunction()
{}
myFunction.value = 0;
Run Code Online (Sandbox Code Playgroud)
因为,正如我在上面解释的那样: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
Run Code Online (Sandbox Code Playgroud)
如果要访问该函数内的函数属性,最简单的方法是像任何其他对象一样引用该函数:
function myFunction()
{
this.value = myFunction.value;
}
myFunction.value = 101;
Run Code Online (Sandbox Code Playgroud)
警告:
只是一个友好的警告:this在没有检查全局变量的情况下在函数中使用是不太安全的......如果在没有显式上下文的情况下调用函数,JS 默认使用global(window)对象.这意味着为任何对象分配属性的每一行恰好也指向了一个全局变量:this
function myFunction()
{
this.foo = 'bar';
}
myFunction();
console.log(window.foo);//logs bar EVIL GLOBAL
Run Code Online (Sandbox Code Playgroud)
有几种方法可以防止全局对象被全局变量弄乱:
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
}
Run Code Online (Sandbox Code Playgroud)
您需要instance使用new关键字创建一个.
function myFunction() {
this.value = 0;
}
var inst1 = new myFunction();
alert(inst1.value); // this works
Run Code Online (Sandbox Code Playgroud)
现在这对应于当前对象,它会获取属性的相应值.
在一天结束时..函数仍然是对象 ..所以当你分配时它不会抱怨myFunction.value = 0..它可能会让你感到困惑,因为你在函数内外都使用了值(键).用它替换它
myFunction.abc = 'Hello'
alert(myFunction.abc) still works
Run Code Online (Sandbox Code Playgroud)
但它不会反映在实际的myFunction中,因为你尚未调用该函数.