2011-09-08 65 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未被排除),構造函數的()是可選的(除非有必要的參數(在某些語言中))。