2012-11-16 136 views
5

我試圖尋找在ES6自己的草稿,但我不知道在哪裏看:`this`在全球範圍內ECMAScript中6

誰能告訴我,如果this在ES6不一定指的是全球目的?此外,該對象是否與全局範圍具有相同的成員?

如果你可以回答ES5,那也是有幫助的。

我知道全局範圍內的this指的是瀏覽器和大多數其他ES環境(如Node)中的全局對象。我只是想知道這是規範定義的行爲,還是實現者添加的擴展行爲(如果這種行爲將在ES6實現中繼續)。另外,全局對象與全局範圍始終是一回事嗎?還是有區別?


更新 - 爲什麼我想知道:我基本上是試圖找出如何讓全局對象可靠地ES5 & 6.我不能依靠window,因爲這是特定於瀏覽器,我也不能依靠global,因爲它特定於像Node這樣的環境。我知道Node中的this可以參考模塊範圍中的module,但我認爲它在全球範圍內仍然指global。我想要一個跨環境的兼容方式來獲取全局對象(如果可能的話)。似乎在全球範圍內所有我知道的this的環境中都這樣做,但我想知道它是否是實際規範的一部分(並且在我可能不熟悉的任何環境中如此可靠)。

我還需要知道規範中的全局範圍和全局對象是否是相同的東西。換句話說,全球範圍內的所有變量都與globalobject.variable_name相同?


更新2 - 我想要做的事:

我已經開發了一些ES6 shims for ES5 environments。我想知道最好的方法來(1)檢查ES6內置插件是否已經存在,以便在可能的情況下使用它們而不是我的墊片,以及(2)如果內置插件可以添加墊片到全局範圍,還不存在。

目前我下面這個模式:

(function() { 

    // Indirect eval to run in global scope. 
    // (We get whatever "this" is in global scope, hoping that it's the global object... 
    // Whether this line does what I want it to is the crux of my question.) 
    var global = (0, eval)('this'); 

    // If Symbol does not already exist in global scope, 
    if (!global.Symbol) 

     // Then add Symbol to global scope. 
     global.Symbol = (function() { 

      // ... 
      // Return my Symbol shim 

     })(); 

})(); 

還有一些其他的可能性(1),但在這一天,我需要一種方法來添加一些全局範圍內沒有使用var結束全球範圍內(因爲這會覆蓋內置,因爲我可以檢查他們,由於var提升[至少在天真的情況下,也許我可以間接evalvar聲明以及?])。我希望我的代碼能夠在嚴格模式下運行,這樣就可以解決問題。

我發現,通過ES5規範,間接eval在全局範圍內執行代碼。所以我至少能夠做到這一點。我的問題是,如果我在全局範圍內得到this,(1)檢查該對象的屬性是否讓我知道全局範圍內是否已經存在內置?和(2)將添加屬性到該對象允許我將變量添加到全局範圍?

+3

它應該像以前的ES規格一樣工作,因爲'this'不是ES6特有的。 「this」的含義取決於它的用途,並不總是全局對象。 – Jay

+0

瞭解;這就是爲什麼我要求「在全局範圍內」,瀏覽器中的這個「和」window也是全局對象。但是,我不知道這是在ES中指定的還是僅僅是該語言的瀏覽器擴展。 –

+1

只要你不喜歡SES,間接評估技巧將可靠地工作。一旦你擁有全局對象,你可以分配給它並檢查屬性,這將做你想要的。在es6中,除了Andreas關於let,const等的說法之外,還有一些模塊具有自己的全局私有的全局對象作爲外部作用域,因此除非直接引用外部全局對象,否則無法訪問或修改外部全局對象(像node.js自動定義'global',例如,會給你一個對外部全局的引用)。 – 2012-11-19 04:59:28

回答

2

是的,全球範圍內的this將繼續引用ES6中的全局對象。 (一般來說,ES6應該是完全向後兼容的,即任何可以在ES5中工作的代碼也可以在ES6中工作)。

但是,「全局範圍」的概念將不再與ES6中的全局對象相同。它引入了新的聲明表單,這些表單在詞彙範圍內(letconst,classmodule等等)。上次會議的結論是,這些都不會顯示爲全球對象的屬性。這有很多技術和方法的原因,但底線是最好避免直接使用全局對象(這一直是事實,但在ES6中更是如此)。

有什麼特定的東西需要全局對象嗎?

+0

嘿安德烈亞斯,謝謝你提供你的專業知識!我已經回答了你爲什麼要在原始帖子的** Update 2 **中放置全局對象的問題。你可以看一下,看看我所遵循的模式是否合適?謝謝! –

0

大部分是。

在任何非物體通過this(或不設置this)將引用全局對象:

(function(global){ /* do stuff! */ }(this)); 

這種行爲是爲了留在ES6(可以理解的向後兼容性問題)。這就是我所知道的大多數多平臺(瀏覽器/節點)插件正在訪問全局對象的原因。例如:https://github.com/documentcloud/underscore/blob/master/underscore.js#L12

雖然服務器上的插件只能訪問this,因爲module(它被導出)。但是,這就是你想要的節點。您的全局空間不會被清除(除非手動完成或在服務器重新啓動時完成)。所以它在所有客戶端連接之間共享;將任何事物分配給全球空間並不是一個好主意。


如何this唯一的顯着區別是JavaScript的「版本」之間的處理是在strict mode,它會拋出,如果nullundefined傳遞給callapplybind(在的位置的誤差this value)。在非嚴格模式下,this僅被強制爲全局對象。

"use strict"; 
foo.apply(null); // Throw error 

希望得到這個幫助!

+2

你可能剛剛在你的措辭中不清楚,但'foo.apply(null);'不會在嚴格模式下拋出錯誤。 'function foo(){this.doSomething(); }'在嚴格模式下拋出一個錯誤,如果沒有'this'(例如'this'爲'null'或'undefined')。這可能是你想要說的,但你可能想爲後代寫得更清楚。 –