解决掉你心中 js function与Function的关系的疑问
前言
在網上有很多關于js function 與 Function直接關系的文章。
但是我感覺過于抽象化了,那么如何是具體化的解釋?
正文部分為個人理解部分,如有不對望指出。
正文
<script>
if((function(){}).constructor === Function)
{
console.log(true);
}
</script>
我寫了一段這個代碼,答案為true。
這就是function 與 Function的關系。
看下Function的定義:
Function 構造函數創建一個新的 Function 對象。直接調用此構造函數可用動態創建函數,但會遭遇來自 eval 的安全問題和相對較小的性能問題。然而,與 eval 不同的是,Function 構造函數只在全局作用域中運行。
然后還給出了這樣一個結論:
每個 JavaScript 函數實際上都是一個 Function 對象。
重新理解一下,Function的定義。
第一句話很好理解,就是可以創建一個Function對象。第二句好也好理解,就是會有安全漏洞和性能問題,詳細部分可看eval的安全問題,至于為什么低效,官方解釋是:因為使用后者創建的函數是跟其他代碼一起解析的。
第三句話,什么叫"Function 構造函數只在全局作用域中運行"?
var func = new Function("alert(x+y);");
var test = function () {
var x=1,y=2;
func();
eval("x+y");
}
就是func()運行會報錯。而eval("x+y")是成功的。
因為func()是在全局作用域中運行。
如果是這樣:
var x=1,y=2;
var func = new Function("alert(x+y);");
var test = function () {
var x=1,y=2;
func();
eval("x+y");
}
test();
那么會彈出3;
當然這里說eval是在局部變量中運行也比較絕對,因為eval的引用變量是在全局中運行的。
var global=eval;
global("x+y");
這樣就在全局中運行,好吧,這不是該篇的重點。
那么這種Function 對象和申明函數有什么區別呢?前面已經說明了,Function對象是在全局中運行,而聲明函數是在局部中運行。
我找了一個例子:
var x = 10;
function createFunction1() {
var x = 20;
return new Function('return x;'); // 這里的 x 指向最上面全局作用域內的 x
}
function createFunction2() {
var x = 20;
function f() {
return x; // 這里的 x 指向上方本地作用域內的 x
}
return f;
}
var f1 = createFunction1();
console.log(f1()); // 10
var f2 = createFunction2();
console.log(f2()); // 20
看到這里,以為結束了?下面是本文的核心思想部分。
我們如何才能夠,用function的方式建立出Function對象的效果?或者說我們如何模擬new Function() 到底發生了什么。
var x=1,y=2;
var func = new Function("alert(x+y);");
var func1= function ()
{
alert(x+y);
}
console.log(func);
console.log(func1);
打印出來func,是一個匿名的函數。
匿名函數自帶是閉包效果,在這里我似乎找到了答案,現在我們就來模擬出new Function();
function main() {
var x = 5;
var y = 6;
FunctionObj = function () {
alert(x + y);
};
function func() {
var x = 1;
var y = 2;
var Newfunc = FunctionObj;
Newfunc();
}
func();
}
main();
FunctionObj();
彈出的結果是11,另一個彈出的還是11;
在這里我假設啟動的是main主函數,x與y是全局變量。
然后在func中的:
var func = FunctionObj;
func();
假設為new Function(),也就是說去假設構建一個Function 對象。
這樣實現的其實就是在全局變量中創建了FunctionObj變量,然后賦值給了func,然后再執行func的時候自然就在main變量中了,因為匿名函數本身就閉包。
對應為:
var x=5;
var y=6;
function func()
{
var x=1;
var y=2;
var NewFunc= new Function("alert(x+y)");
NewFunc();
}
func();
繼續變化一下,模擬Function 做了什么:
var x=5;
var y=6;
function func()
{
var x=1;
var y=2;
var NewFunc= Functionsimulation();
NewFunc();
}
function Functionsimulation()
{
var global=eval;
return eval("(function(){return function(){alert(x+y)}})()");
}
func();
彈出的結果依然是:11;
總結
回過頭來,再看一下這段話:
每個 JavaScript 函數實際上都是一個 Function 對象。
new Function 只是將匿名包,綁定到了一個全局變量了,這樣它的this永遠固定,運行時,永遠是在全局中運行。
至于聲明函數,因為是動態的運行,所以我們訪問的以局部優先,也可以理解為綁定的為局部變量。
以上是個人理解,如有不對望指出。
總結
以上是生活随笔為你收集整理的解决掉你心中 js function与Function的关系的疑问的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ABAP-关于 LUW
- 下一篇: 20155336 2016-2017-