2011-09-08 66 views
5

考虑下面的代码:JavaScript中的新功能 - 这是什么意思?

var f = function() { return 10; } 
typeof f;       // returns "function" 
f();        // returns 10 

var g = f; 
g();        // returns 10, obviously 

var h = new f; 
h;        // console evaluates to f - ???? 
h();        // Type error - called_non_callable 
typeof h;       // returns "object" 

那么,什么是h这里? Chrome控制台似乎将其评估为f,但无法调用。 “新”这样的功能意味着什么?现在h与f有什么关系?

顺便说一句,这两条线似乎相当于:

var h = new f; 
var h = new f(); 

是什么回事?

+2

可能重复的[JavaScript中的'new'关键字是什么?](http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript) –

回答

4

混淆的根源在于Chrome在其控制台上表示对象的方式。

在你的实施例中的表达new f()被表示为在Chrome的控制台输出“f”,但正如该特定控制台的一个单纯的“方便”,例如,记录下列对象:

({constructor: function Foo(){}}); 

将显示它表示为“Foo”。基本上控制台试图找到表示其构造函数您的对象是实例

因此,控制台显示为f,但您未记录该功能,new运算符会生成一个继承自f.prototype的对象。

你从函数返回10,但既然你用new调用它,返回类型是原始,该值将被丢弃,新创建的对象继承返回的形式f.prototype

例如:

var F = function() { return 10; }; 
F.prototype.inherited = 'foo'; 

var h = new F(); // the 10 returned is ignored 
h instanceof F; // true 
h.inherited; // "foo" 

在另一方面,如果你从一个构造函数的对象实例的new运营商创建scened后面(从构造函数的原型继承)返回一个对象将丢失,例如:

var F = function() { return {}; }; 
F.prototype.inherited = 'foo'; 

var h = new F(); // the empty object is returned 
h instanceof F; // false 
h.inherited; // undefined 

是,new f;new f();是完全等价的,尽管人们推荐使用括号加清晰,你的代码。

+0

其中一个最好的对SO的解释!感谢您保持简单。 – demisx

4

这是面向对象在JavaScript中是如何工作的。如果你在一个函数上调用new,这个函数将被视为它是一个类的构造函数(关键字class定义一个类似于其他语言的类在js中不存在)。

所以调用var h = new f();使h成为类f的对象,并且对象本身不可调用(这就是为什么你得到called_non_callable)。

如果你想给你的“类”一些methots

,你应该这样做是这样的:

function cat(name) { 
    this.name = name; 
    this.talk = function() { 
     alert(this.name + " says meeow!") 
    } 
} 

cat1 = new cat("felix") 
cat1.talk() //alerts "felix says meeow!" 

cat2 = new cat("ginger") 
cat2.talk() //alerts "ginger says meeow!" 

这是从this tutorialpage 2一个例子。欲了解更多信息,请阅读或ask Google for object-orientation in JavaScript

1

在JavaScript中,函数不仅仅是函数,它们不仅仅是对象;它们也用于为类型定义构造函数。

一般来说,当你有一个函数f时,该函数定义了一个类型,无论这是否是有意的。因此,线

var h = new f(); 

定义对象h其类型为f

我从来没有见过的线

var h = new f; 

但我假设它一样的其他线路。

2

我推荐阅读https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/this,特别是关于“功能上下文”的章节。

简而言之,当你new功能,您要创建一个新的对象: var h = new f;

这是说:“创建名为f类型的h的变量引用的新对象”。该函数然后被视为构造函数而不是您期望的。

一旦对象被创建,它就不再被调用(这就是为什么你遇到线h()上的错误。

在大多数语言中(Javascript未被排除),构造函数的()是可选的(除非有必要的参数(在某些语言中))。