2011-11-28 96 views
9

我正在學習Javascript,我一直在使用PHP大約10年,所以我對JavaScript有一些瞭解,主要是使用jQuery並將它們一起黑客攻擊,我認爲是時候我花點功夫去學習它了所以我一直在閱讀它。Javascript函數和對象

下面是我定義和調用某些函數的示例。

方法1

function testFunction1() { 
    console.log('TestFunction1() was ran'); 
} 
testFunction1(); 

方法2

var testFunction2 = function() { 
    console.log('TestFunction2() was ran'); 
} 
testFunction2(); 

方法3

var TestFunction3 = { 
    flag: function() { 
     console.log('TestFunction3.flag() was ran'); 
    }, 
    unflag: function() { 
     console.log('TestFunction3.unflag() was ran'); 
    } 
}; 
TestFunction3.flag(); 
TestFunction3.unflag(); 

方法4

var TestFunction4 = { 
    Like: { 
     comment: function() { 
      console.log('TestFunction4.Like.comment() was ran'); 
     }, 
     user: function() { 
      console.log('TestFunction4.Like.user() was ran'); 
     } 
    }, 
    Unlike: { 
     comment: function() { 
      console.log('TestFunction4.Unlike.comment() was ran'); 
     }, 
     user: function() { 
      console.log('TestFunction4.Unlike.user() was ran'); 
     } 
    } 
}; 
TestFunction4.Like.comment(); 
TestFunction4.Like.user(); 
TestFunction4.Unlike.comment(); 
TestFunction4.Unlike.user(); 

確定,所以我明白方法1和2是隻是一個基本的函數調用。

1)
方法3和4是在我的問題入手,從其他崗位和閱讀,我不能告訴,如果這些仍然被認爲是與命名空間基本功能應用,或者,如果這些將被視爲對象?

2)
我曾經見過有時一個對象將與new字跑不過這一切都在瀏覽器中調用工作正常,所以我猜測這是不是一個對象?如果它不是一個對象,我將如何使它成爲一個對象?

3)
實施例3和4是幾乎相同的,不同的是實施例4已功能而定義的1級更深然後例3中,是有一個名稱,例如圖3和4或者他們認爲是相同的東西?

4)
最後,在所有的4個例子中,這4種方法中的任何一種都優先於其他方法嗎?

對不起,所有在1中的問題,但他們都是相關的,我不認爲我需要爲此啓動4個單獨的問題。

+0

你或許會從閱讀中受益:http://bonsaiden.github.com/JavaScript-Garden/和至少審查[ECMAScript標準(HTTP: //www.ecma-international.org/publications/standards/Ecma-262.htm)。 –

+1

一切都是一個對象,除了'null'和'undefined'外。 – zzzzBov

+1

如果您有空閒時間,請查看Douglas Crockford的[The Good Parts](http://www.amazon.com/exec/obidos/ASIN/0596517742/wrrrldwideweb)。相對較短的書,閱讀後,你的問題的答案應該是清楚的,我認爲。 – Jeroen

回答

4

3是一個對象。它具有對象屬性,它們本身具有作爲函數的屬性。 4是相同的想法,只是少嵌套。

就使用new關鍵字而言,這只是創建對象的一種方法。當使用new調用函數時,這稱爲構造函數調用。這是調用函數的四種方法之一。其他三個完整性爲方法調用,函數調用應用調用

如果你想使用的功能作爲構造你會,按照慣例,用大寫字母開頭,然後用new關鍵字調用它。這會基於Object.prototype創建一個空白對象,並將其設置爲等於this。當使用對象創建的這個模式,你的屬性直接將其添加到this添加到您生成的對象,即對象的this.foo = 12

方法將通過修改函數的原型被添加。

YourConstrutor.prototype.newMethod = function() { 
    alert(this.foo); 
}; 

注意,使用構造自帶了很多的困難,特別是如果你想實現繼承

對象可以通過從「常規」函數返回他們創造更簡單:

function createCar() { 
    return { 
     prop1 : 12, 
     someFunc: function() { 
     alert(this.prop1); 
     } 
    } 
} 

這也使信息隱藏簡單:

function createCar() { 
    var protectedInfo = "haha I'm protected"; ///not visible outside this function 
    return { 
     prop1 : 12, 
     showProtectedData: function() { 
     alert(protectedInfo); 
     }, 
     someFunc: function() { 
     alert(this.prop1); 
     } 
    } 
} 

(您也可以使用構造函數實現隱藏信息,但受保護的信息將不會被顯示給您放置在原型上的方法;受保護的信息,就只有手動添加到this)方法可見

這裏唯一的缺點是,創造將是稍微慢,因爲它創建someFunc方法從頭每次;作爲原型的一部分,構造函數會存在一次。

4.哪個更好?如果你只是想創建一個單一的對象,然後使用3或4.簡單。

如果你想重複創建一個對象,然後這取決於。你會創造數以萬計的這些對象,這樣速度至關重要嗎?如果是這樣,你可能會需要一個構造函數。如果不是,那麼這取決於你最舒適的。我發現一個簡單的函數可以返回一個最清晰,最靈活的對象,但這只是我的偏好。許多比我更聰明的開發人員更喜歡構造函數。

1
  1. 3和4仍然是函數,但它們也是對象。 1和2也是對象和功能。所有函數都是對象 - JavaScript具有一流的功能。

  2. 它實例化一個對象。用new調用的函數是構造函數。他們創建對象。

  3. 他們是完全一樣的東西。與#1一樣,嵌套級別對任何類型都沒有影響...

  4. 不,因爲它們都是等效的。 A FunctionObject,它在哪裏並不重要。但是,一般來說,爲避免命名空間的使用,您可以避免繁重的嵌套操作,因爲它可以減慢代碼的速度,而沒有任何明顯的好處。 JavaScript的設計並不是真正在考慮命名空間。

0

AFAIK

1)在JS的所有功能都是對象。在3的情況下,是的,它會被視爲一個對象,因爲它在大括號內

3)它們是相同的東西,但是一種方法可以使爵士樂的東西成爲'返回'其中一個最高等級的屬性而不是另一個,它基本上隱藏了非返回函數,並給你一種創建公共和私有方法的方法。

4)大概4是最接近我想你想,並遵循一些明智的做法,但安德魯說,我會傾向於改變4弄成這個樣子:

var TestFunction4 = (function(){ 
    return { 
     flag: function() { 
      console.log('TestFunction4.flag() was ran'); 
     }, 
     unflag: function() { 
      console.log('TestFunction4.unflag() was ran'); 
     } 
    } 
})(); 
TestFunction4.flag(); 
TestFunction4.unflag(); 

注意括號在該方法的尾部,迫使功能立即執行,並使自己繳費到運行時應用程序的其餘部分之前(在比如說而言,智能感知)

編輯:

這是我會使用'私人「功能迴應t ○「你爲什麼要這麼做」的評論:

var TestFunction4 = (function(){ 
    //private function 
    var private = { 
     aPrivateFunction: function(a) { 
      return a + 1; 
     } 
    } 
    //public return object 
    var public = { 
     flag: function() { 
      console.log('Calling private function aPrivateFunction(10) expecting 11'); 
      console.log('result' + private.aPrivateFunction(10)); 
      console.log('TestFunction4.flag() was ran'); 
     }, 
     unflag: function() { 
      console.log('TestFunction4.unflag() was ran'); 
     } 
    } 
    //return things to expost publicly 
    return public; 
})(); 
+0

你的4)例子甚至沒有運行......你爲什麼要這樣做?函數可以像對象一樣容易被覆蓋。 – Ryan

+0

上面的例子純粹是一個例子,因爲它運行時需要'返回'一個包含標誌和unflah函數的對象或屬性,正如我在第3點的答案中提到的,我將更新代碼以顯示您會運行它 – dougajmcdonald

+0

在回答'爲什麼你想要這樣做'這是模塊化的前兆。一旦你返回了你希望訪問的函數的對象,你可以在TestFunction4對象內部定義不屬於返回對象的'private'函數/變量。雖然TestFunction4可以被覆蓋,但是內部的值不能被AFAIK訪問。我將再次更新該函數,以顯示您可以運行的示例。 – dougajmcdonald