您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關ES6中如何實現new Function()語法的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
具體如下:
學習《ECMAScript6入門》中的模板字符串的案例中看見了new Function()創建函數的語法:
let str = 'return ' + '`Hello ${name}!`'; let func = new Function('name', str); func('Jack') // "Hello Jack!"
上面的代碼傳入name參數和字符串函數體,字符串函數體由模板字符串提供,非常簡潔方便。
為理解new Function,于是找到了下面這篇文章:
下文翻譯自:https://javascript.info/new-function
這里有一個很少被用到的新建函數的方法,但是有時候不得不使用它。
語法
新建函數的語法:
let func = new Function ([arg1[, arg2[, ...argN]],] functionBody)
換句話說,函數的參數(或更確切地說,各參數的名稱)首先出現,而函數體在最后。所有參數都寫成字符串形式。
通過查看示例,可以更容易理解。這是一個有兩個參數的函數:
let sum = new Function('a', 'b', 'return a + b'); alert( sum(1, 2) ); // 3
如果所要新建的函數沒有參數,那么new Function()只有一個函數體參數:
let sayHi = new Function('alert("Hello")'); sayHi(); // Hello
這個方式與其他方式最主要的不同點在于,函數是由在運行時傳入的字符串創建的。
之前的所有聲明都要求程序員在腳本中編寫功能代碼。
但new Function允許將任何字符串轉換為函數。例如,我們可以從服務器接收新函數然后執行它:
let str = ... receive the code from a server dynamically ... let func = new Function(str); func();
它在非常特殊的情況下使用,例如當我們從服務器接收代碼時,或者使用模板動態編譯函數。對此的需求通常出現在開發的進階階段。
閉包(Closure)
通常,函數將它所創建的位置記錄在特殊屬性[[Environment]]中。 它引用了創建地點的詞法環境。
但是當使用new Function()創建函數時,其[[Environment]]不是引用當前的詞法環境,而是引用全局環境。
function getFunc() { let value = "test"; let func = new Function('alert(value)'); return func; } getFunc()(); // error: value is not defined
與常規方法比較:
function getFunc() { let value = "test"; let func = function() { alert(value); }; return func; } getFunc()(); // "test", 來自getFunc的詞法環境
這個特殊的new Function表面看起來很奇怪,但在實踐中顯得非常有用。
想象一下,我們必須從字符串創建一個函數。在編寫腳本時不知道該函數的代碼(這就是我們不使用常規函數的原因),但在執行過程中將會知道。我們可能會從服務器或其他來源收到它。
我們的新函數需要與主腳本進行交互。
也許我們希望它能夠訪問外部的局部變量?
問題是在JavaScript發布到生產之前,它是使用minifier壓縮的——一個通過刪除額外的注釋,空格來縮小代碼的特殊程序,而且 - 重要的是,會將局部變量重命名為較短的變量。
例如,如果一個函數中有let userName,那么minifier會替換它為let a(或者如果a被占用,則用另一個字母替換),這個過程會在任何地方進行。這通常是一件安全的事情,因為被替換的變量是局部的,函數外部沒有任何東西可以訪問它。并且在函數內部,minifier取代了它的每一個提及。Minifiers很聰明,他們會分析代碼結構,所以他們不會破壞任何東西。他們不是只會愚蠢地發現和替換。
但是,如果new Function可以訪問外部變量,那么它將無法找到userName,因為userName在代碼縮小后才作為字符串傳入。
所以,即使我們可以在new Function中訪問外部詞匯環境,我們也會遇到minifiers的問題。
而這時,new Function的“特色”可以讓我們免于犯錯。
它強制執行更好的代碼。如果我們需要將某些東西傳遞給由new Function創建的函數,我們應該將它作為參數顯式傳遞(可以避免直接讀取外部變量時產生的問題)。
我們的“sum”函數實際上是這樣正確使用的:
let sum = new Function('a', 'b', 'return a + b'); let a = 1, b = 2; // 外部變量作為參數傳入 alert( sum(a, b) ); // 3
總結
語法:
let func = new Function(arg1, arg2, ..., body);
歷史原因,參數也可以以逗號分隔的列表的形式給出。
這三個意思相同:
new Function('a', 'b', 'return a + b'); // 基礎語法 new Function('a,b', 'return a + b'); // 逗號分隔 new Function('a , b', 'return a + b'); // 逗號加空格分隔
使用new Function創建的函數,其[[Environment]]引用全局詞法環境,而不是包含該函數的外部詞法環境。因此,他們不能使用外層的變量。但這確實很好,因為它可以使我們免于錯誤。明確地傳遞參數在架構上是一種更好的方法,并且不會在使用minifiers時不會產生問題。
感謝各位的閱讀!關于“ES6中如何實現new Function()語法”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。