2012-06-15 134 views
7

我剛纔在閱讀如何'創建一個JavaScript庫',我遇到了這些代碼,讓我想把我的頭髮撕掉。這些代碼片段如何工作?

這裏是得到了我的大腦在海里代碼:

if (window === this) { 
    return new _(id); 
} 

_(ID)就是在此代碼包含函數名。如果你需要自己查看它,下面是其餘的代碼。

function _(id) { 

// About object is returned if there is no 'id' parameter 
var about = { 
    Version: 0.5, 
    Author: "Michael Jasper", 
    Created: "Fall 2010", 
    Updated: "23 November 2011" 
}; 

if (id) { 

    // Avoid clobbering the window scope: 
    // return a new _ object if we're in the wrong scope 
    if (window === this) { 
     return new _(id); 
    } 

    // We're in the correct object scope: 
    // Init our element object and return the object 
    this.e = document.getElementById(id); 
    return this; 
    } else { 
    // No 'id' parameter was given, return the 'about' object 
    return about; 
    } 
}; 

我從來沒有見過'返回新功能',但我很想了解它的功能。

另一段代碼:

_.prototype = { 
    hide: function() { 
      this.e.style.display = 'none'; 
      return this; 
    } 

    show: function() { 
      this.e.style.display = 'inherit'; 
      return this; 
    } 
}; 

我知道這個代碼添加新的方法到_對象,但爲什麼他們「返回這個」?我試過沒有,它工作得很好。

最後一兩件事,鏈接到文章http://www.mikedoesweb.com/2012/creating-your-own-javascript-library/

+0

Return this?那麼也許你可以在它後面追加更多的東西?只是猜測 – Anonymous

+6

'return this'啓用鏈接,如'magic()。do()。stuff()'。 –

+0

是的,鏈接是我的意思,它就像jquery,但jquery有點複雜,並返回許多對象 – Anonymous

回答

16

代碼的第一位基本上是試圖檢測如何「構造」函數被調用......

在JavaScript中,你可以使用一個函數有兩種方式來創建一個對象:

function _(id) { 
    this.someProperty = "stuff"; 
    //Do more stuff to "this" 
    return this; 
} 

//in this scenario, the "this" object will be the window object 
var myObject = _(id); 
console.log(window.someProperty); //outputs "stuff"; 
console.log(myObject.someProperty); //outputs "stuff"; 

//in this scenario, the "this" object is what get's actually returned... 
var myObject = new _(id); 
console.log(window.someProperty); //outputs "undefined" 
console.log(myObject.someProperty); //outputs "stuff" 

因此,對於

if (window === this) { 
    return new _(id); 
} 

檢查僅僅是存在,以確保您不會意外調用構造函數沒有new關鍵字。這將是不好的,因爲你將分配給該對象的任何屬性將立即分配給window命名空間......這將是不好的。


爲你的第二個問題,筆者使用return this;在每個方法的末尾爲fluent interface design pattern

這允許方便和美觀的對象操作。這方面的一個常見的例子是jQuery的,在那裏你可以鏈到方法單一對象...

$(".some-css-selector").click(function() { 
    ... do something to the selected objects during the "click" event 
}).keyup(function() { 
    ... do something to the same objects during the "keyup" event 
}); 

編輯:

從道格拉斯:多一點額外的響應下面W3Geek的評論信息Crockford的書「Javascript:The Good Parts」(如果你進入JS,完全是一個很好的閱讀......只有70頁,但其中每一個都值得閱讀)。


JavaScript的new運營商創建一個新的對象,從操作數的原型成員繼承,然後調用操作,新的對象綁定到this。這使操作數(最好是構造函數)有機會在將新對象返回給請求者之前對其進行自定義。

如果您忘記使用`new運算符,那麼您將得到一個普通的函數調用,並且這將被綁定到全局對象而不是新對象。這意味着你的函數在試圖初始化新成員時會破壞全局變量。這是一件非常糟糕的事情。

...

構造函數是被設計爲與new前綴使用的功能。前綴new根據函數的原型創建一個新對象,並將該對象綁定到暗含參數this的函數。如果您忽略使用前綴new,則不會創建新對象,並且將this綁定到全局對象。這是一個嚴重的錯誤。


+0

所以基本上'這'會污染全球範圍,如果我們使用不正確,並且'檢查'被放置在那裏以防止這種情況發生,那麼正確?我的問題是,窗口命名空間有什麼問題?我看到這麼糟糕,但從來沒有看到這麼多。 – W3Geek

+0

正確。向「窗口」對象添加屬性是不好的,因爲有許多其他框架可以訪問它(以及USE IT)...例如,人們修改'window.location.href'對象(當前url你的瀏覽器)一直「瀏覽」到一個新的頁面......如果你突然爲你的'_'對象添加一個位置屬性,它會完全打開window.location屬性...一般你應該只是把你正在控制的東西放在自己的命名空間中,以確保它沒有任何副作用 –

+2

注意:這裏似乎有一些體面的答案[關於「泄漏」變量到全局命名空間](http:///stackoverflow.com/questions/5951228/what-is-meant-by-leaking-into-global-scope)。關於它的討論通常很多,不適合評論:) –

6

return this使您能夠鏈接方法調用。你可以做一些很酷很有用的事情,比如_.show().hide()。 :)