javascript - 關于具名的IIFE內部對函數自身再賦值問題?
問題描述
+function foo(){foo=10;//我的問題代碼 console.log(foo);//方法自己}();console.log(typeof foo);//undefined 觀察是否全局污染
我想問 函數foo內部對foo再賦值的這個10去哪了,還有同名函數foo是如何阻止全局污染的,求解求擴展
問題解答
回答1:題主能問這個,可以的.不過這題能通過自己實踐解決掉...
首先題主對于IIFE的寫法沒問題,IIFE的寫法好多,常見的就是@ewind說的這個和:
(function(){}())
還有不常見的:
!function(){ /* code */ }();~function(){ /* code */ }();-function(){ /* code */ }();+function(){ /* code */ }();
然后再說代碼:在函數里給當前函數名賦值時:foo = 10; 無效.(贊同@ewind,這里會忽略,應該有更合理的說法.)JS解析器會忽略掉它.我在Chrome控制臺執行的結果是:
function foo(){ foo=10;//我的問題代碼 console.log(foo);//方法自己}undefined// 上面typeof foo的結果
這就證明了上面我說的忽略.然后因為IIFE模擬了塊作用域,外部環境訪問不了內部的變量.所以就是undefined.
@ewind說因為foo是匿名函數然后怎樣怎樣.明顯概念搞混了.foo函數并不是匿名函數.
function [name]([param] [, param] [..., param]) { statements }name函數名,可以省略。當省略函數名的時候,該函數就成為了匿名函數。
MDN
回答2:首先,貼出的代碼是不完整的。完整版應該是這樣
(function foo(){ foo = 10 console.log(foo) // [Function: foo]})();console.log(typeof foo) // undefined
這確實看起來比較反直覺,因為沒有采用 var 聲明的 foo 并沒有污染全局作用域。
但如果函數內聲明的變量名不是 foo,就很符合直覺了,如下:
var bar = 1;(function foo(){ bar = 10})();console.log(typeof foo) // undefinedconsole.log(bar) // 10
所以為什么函數內聲明的變量和函數名同名時,會發生問題呢?可以看這個示例:
(function foo(){ console.log(foo) // [Function: foo] console.log(arguments.callee) // [Function: foo] console.log(foo === arguments.callee) // true})();
在立即執行的函數帶有 foo 這一函數名后,調用時的 arguments.callee 其實就是對 foo 的引用了。比較二者可以發現此時 foo 就是函數對象。此時賦值操作并不能生效,遇到未加 var 聲明的 foo 變量時,解釋器查找到的也是這個函數對象,從而不會在全局作用域下產生污染。
相關文章:
1. HTML5禁止img預覽該怎么解決?2. javascript - vue+iview upload傳參失敗 跨域問題后臺已經解決 仍然報403,這是怎么回事啊?3. python - django 按日歸檔統計訂單求解4. objective-c - 從朋友圈跳到我的APP 如何實現?5. 百度地圖api - Android 百度地圖 集成了定位,導航 相互的jar包有沖突?6. 網頁爬蟲 - python爬蟲用BeautifulSoup爬取<s>元素并寫入字典,但某些div下沒有這一元素,導致自動寫入下一條,如何解決?7. javascript - vscode alt+shift+f 格式化js代碼,通不過eslint的代碼風格檢查怎么辦。。。8. 請教一個python字符串處理的問題?9. sql語句 - mysql中關聯表查詢問題10. 怎么可以實現在手機瀏覽器看到鏈接的title屬性,就是鼠標放上去會有一個tip效果的
