javascript中的对象和函数

时间:2012-11-21 18:52:03

标签: javascript scope

  

可能重复:
  Javascript: Do I need to put this.var for every variable in an object?

我正在努力理解javascript中的函数和对象。据说功能也是对象,对象是一种“关联数组”,即键值对的集合。我明白如果我写

function myFunction() {
    var value = 0;
}
alert(myFunction.value); //then this gives me "undefined"

因为变量具有功能范围。但如果我写

function myFunction() {
    this.value = 0;
}
alert(myFunction.value); //then this gives me "undefined" too.

但最后,如果我写

function myFunction() {
    this.value = 0;
}
myFunction.value = 0;
alert(myFunction.value); //then this gives me 0

所以我可以从“外部”给myFunction属性“value”。有人可以解释发生了什么以及为什么this.value = 0;不会创造属性“价值”。

6 个答案:

答案 0 :(得分:13)

让我们分别看看所有三个案例:

function myFunction()
{
    var value = 0;
}

在这里,您要在函数范围内声明一个变量。每次调用该函数时,都将创建该变量(并将分配内存)。当函数返回时,变量超出范围 - 变量value被标记并将被GC。无法从范围“higher”访问范围,而不是此函数的范围...如果此函数在其范围内定义了函数,则该函数将可以访问变量value (查看闭包以获取更多详细信息)。底线:变量仅在调用函数时存在,并且在函数返回后不存在。

function myFunction()
{
    this.value = 0;
}

在这里,您将定义一个函数,该函数可以是构造函数,方法,事件处理程序或上述所有组合。 this是一个引用,它将指向调用该函数的上下文。此上下文是“ad hoc”确定的,可能会有所不同:

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:通常不会是:{/ p>

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;

注意:
只是一个友好的警告:在没有检查全局变量的情况下在函数中使用this是不安全的......如果在没有显式上下文的情况下调用函数,JS使用全局(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
}

答案 1 :(得分:7)

您需要使用关键字创建instance

function myFunction() {
    this.value = 0;
}

var inst1 = new myFunction();

alert(inst1.value);  // this works

现在这对应于当前对象,它会获得属性的相应值。

<强> Check Fiddle

在一天结束时..功能仍然是对象 ..所以当你分配myFunction.value = 0时它不会抱怨..当你使用时可能会让人感到困惑函数内外的值(键) ..  替换为

myFunction.abc = 'Hello' 
alert(myFunction.abc) still works

但它不会反映在实际的myFunction中,因为你尚未调用该函数。

答案 2 :(得分:3)

你误解了javascript原型/对象的概念。

对于第一个例子,你是对的,变量有一个函数范围

第二个例子是错误的。如果要将函数用作“类”,则必须从中创建对象

function myFunction() { this.value = 0; }
var test = new myFunction;

只有这样你才能访问它的'value'属性。为每个'new'语句创建一个新对象。

在第三个示例中,您将向函数添加静态属性,无需创建对象即可访问该属性。不同的技术是

希望有所帮助

答案 3 :(得分:2)

我不确定能否清除所有细微差别,但这可能会有所启发:

function myFunction() {
    this.value = 0;
}
alert( (new myFunction).value);

使用new关键字创建myFunction的新“实例”,允许this用于从函数内部分配值。

答案 4 :(得分:1)

myFunction函数对象。您可以传递它,将其分配给变量,为其分配属性,然后您可以调用它。

分配属性与任何其他对象一样:

myFunction.value = 0;

但是请注意,此时你还没有没有调用这个函数,所以代码里面函数(var value = 0;this.value = 0; )甚至还没有执行。考虑一下:

function someFunction() {
    window.foo = 'foo'; // create a global variable
}

someFunction.bar = 'bar';

console.log(someFunction.bar); // 'bar'
console.log(window.foo); // undefined

someFunction(); // execute the function

console.log(someFunction.bar); // 'bar'
console.log(window.foo); // 'foo'

当您使用myFunction()执行该功能时,只会创建局部变量/在this上设置属性。 this所指的内容取决于如何调用该函数,并在MDN documentation中得到了很好的解释。 this 从不是指函数本身,除非您明确地设置它。

答案 5 :(得分:1)

在javascript中,任何函数也是一个对象,它们是Function的对象,就像Number, Object, Array

一样

一个棘手的问题是new单词,然后它在函数前面添加前缀,它创建一个新对象,并使this关键字指向该新对象(另外一个,它指定函数原型到新对象__ proto __) 在功能上,

this.value = 0;

将为新对象创建一个新属性value,并为其指定0。

如果在功能之前有 new,则为函数调用,this将指向 Window 对象。

尝试在函数中console.dir(this);,您将看到差异。

myFunction.value = 0;

会将属性value创建为myFunction,并为其指定0。因为myFunction只是一个对象(函数)。