2017-09-04 161 views
2

將不勝感激知道爲什麼這樣表達:評估表達const的變量範圍

eval("const a = function() {}; function b() { a(); }; b();") 

拋出一個錯誤在Safari 9.1.2運行時:

ReferenceError: Can't find variable: a

+1

由於Safari是新的Internet Explorer –

回答

2

我懷疑使用const(或let)把這個變量放在內部的eval的範圍內,而在eval內部調用的函數正在使用:

  1. 全球範圍,如果它們被定義爲function X(){};
  2. 內部範圍如果它們被定義爲const X = function(){}

例如,使用const

> eval('const a = function(){ return 42; }; a();') 
42 
> a 
ReferenceError: Can't find variable: a 

使用var

> eval('var a = function(){ return 42; }; a();') 
42 
> a 
function(){ return 42; } 

在支持這種理論:

> eval('const a=function(){return 42;}; const b=function(){return a();}; b();') 
42 
> a 
ReferenceError: Can't find variable: a 
> b 
ReferenceError: Can't find variable: b 

所以,如果我們以相同的方式定義兩個函數,它就會起作用。

現在,讓我們做定義在全球範圍內功能a,而無需使用eval

> a = function(){ return 23;} 

而且,我們從你的問題運行eval代碼(添加return s到兩個函數):

> eval("const a = function(){return 42;}; function b(){return a();}; b();") 
23 

正如你所看到的,功能b使用全球範圍內的a

+0

太棒了!出於某種原因,Safari不會使用'eval()'期間定義的局部變量爲'b'函數創建閉包,這與Chrome不同。我不知道什麼是正確的行爲,海灣該死的野生動物園浪費我的時間! – agoldis