2016-08-25 145 views
-1

我碰到这条信息在书中You Don't Know JS: this & Object Prototypes传来:Javascript:什么是函数属性,它有什么意义?

function foo(num) { 
    console.log("foo: " + num); 
    this.count++; 
} 

foo.count = 0; 
for (var i=0; i<10; i++) { 
    if (i > 5) { 
     foo(i); 
    } 
} 

现在,它后来提到...

当代码执行foo.count = 0,确实它的加入财产count到功能对象foo

我不明白什么是一个函数的属性,以及如何以这种方式声明它。

我明白一个函数也是JS中的一个对象,但我不明白函数属性的意义。此外,一个对象的属性的定义是这样的:

var obj = {name: 'value'}; 

但如何才能foo.count=0 - 出function foo()范围 - foo()下声明属性。

+2

你也可以说'obj.name ='value'来设置对象的属性。当对象是一个函数时完全一样。 – Thilo

+0

@trincot:这本书实际上表达了同样的观点,代码以'console.log(foo.count)结尾; // 0 - WTF?',这不会被OP复制。 – Amadan

+0

我想这个问题更多的是关于'foo.count'。 – trincot

回答

2

看看这段代码:

var foo = { prop: 1 }; 
foo.count = 0; 
console.log(foo.count); // 0 

foo可以是任何对象。它不必被初始化为{}。它可以是一个阵列(例如[1, 2, 3]),日期(例如new Date()),任何其他对象,所以也是一个函数:

var foo = function (num) { 
    console.log("foo: " + num); 
}; 

foo.count = 0; 
console.log(foo.count); 

我写的函数作为分配给变量的函数表达式,以突出指出foo被分配了一个对象。但它也可以与函数声明语法:

function foo(num) { 
    console.log("foo: " + num); 
} 

foo.count = 0; 
console.log(foo.count); 

不要紧哪种对象foo的是,只要是not read-only,你可以添加或覆盖属性的东西,如foo.count = 0

现在,以您的实际示例为例:foo.count似乎应该保留一次该函数调用次数的计数,但它不起作用,因为this不引用该函数,而是引用全局对象(即在浏览器中运行时为window)。

为了解决这个问题,该功能可能看起来像:

function foo(num) { 
    console.log("foo: " + num); 
    foo.count++; 
} 

...但不是通用的,因为你需要“硬编码”的函数的名称。

另一种方法是使用封闭,对于具有count方法,而不是一个数值属性(从this answer拍摄)创建一个函数:

var foo = (function() { 
    var count = 0; 
    // Create the actual function 
    var f = function (num) { 
     console.log("foo: " + num); 
     count++; 
    }; 
    // ... and give it the count method 
    f.count = function() { 
     return count; 
    } 
    // Return that function (it will be assigned to foo) 
    return f; 
})(); // immediately execute the above code: it returns a function 

foo(2); // this increments count from 0 to 1. 

console.log(foo.count()); // 1 
+1

你甚至不应该向新手提及*'arguments.callee'。它已被弃用和遗忘,请离开它。 – Bergi

+1

谢谢您的好评,@Bergie。尽管我已经明确提到了已弃用的状态,但我现在已将其替换为另一个未弃用的解决方案。 – trincot

0

你自己那种回答了这个问题。

函数也是对象。

第一步定义,像这样

function foo(num) { 
    console.log("foo: " + num); 
    this.count++; 
} 

调用foo.count = 0现在刚刚创建的对象foo属性的功能。要阅读更多关于Javascript中的对象,请阅读this

在你的例子中要注意的一件事是你如何调用函数foo。因为this将根据您的调用方式而有所不同。

粘贴您的例子在你的浏览器控制台,然后调用foo.count将打印0

这是因为this必将给全球语境。请阅读here

作为练习,您可以尝试弄清楚如何正确计数。

相关问题