(function ( ){...})( ) IIFE 的原理

你需要明白 IIFE 的原理,我簡單說一下:

function foo() {...}     // 這是定義,Declaration;定義只是讓解釋器知道其存在,但是不會運行。foo();                   // 這是語句,Statement;解釋器遇到語句是會運行它的。

IIFE 并非必須,傳統一點可以這么寫:

function foo() {...}
foo();

那么為什么要 IIFE?

  1. 傳統的方法啰嗦,定義和執行分開寫;
  2. 傳統的方法直接污染全局命名空間(瀏覽器里的?global?對象,如?window

于是,開發者們想找一個可以解決以上問題的寫法。那么像下面這么寫行不行呢?

function foo(...){}();

當然是不能,但是為什么呢?因為?function foo(...){}?這個部分只是一個聲明,對于解釋器來說,就好像你寫了一個字符串?"function foo(...){}",它需要使用解析函數,比如?eval()?來執行它才可以。所以把?()?直接放在聲明后面是不會執行,這是錯誤的語法。

如何把它變得正確?說起來也簡單,只要把?聲明?變成?表達式(Expression)?就可以了。

實際上轉變表達式的辦法還是很多的,最常見的辦法是把函數聲明用一對?()?包裹起來,于是就變成了:

(function foo() {...})    // 這里是故意換行,實際上可以和下面的括號連起來
();

這就等價于:

var foo = function () {...};    // 這就不是定義,而是表達式了。
foo();

但是之前我們說不行的那個寫法,其實也可以直接用括號包起來,這也是一種等價的表達式:

(function foo(){...}());

所以你問有沒有區別?很簡單:木有~

另外,剛才說過轉變表達式的方式很多,的確還有很多別的寫法,比如:

!function foo() {...}();

或者

+function foo() {...}();

這些都可以。

我個人挺偏愛用?void?來轉變表達式,因為此關鍵字不會有返回值。不過這一點真的沒有什么要緊的,就當我“龜毛”好了……

void function () {// 這里是真正需要的代碼
}();

OK,所謂不去污染全局命名空間,是因為 IIFE 創建了一個新的函數作用域,你真正的業務代碼被封裝在其中,自然就不會觸碰到全局對象了。如果你需要全局對象,那就 pass 給 IIFE:

void function (global) {// 在這里,global 就是全局對象了
}(this)    // 在瀏覽器里,this 就是 window 對象

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/247835.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/247835.shtml
英文地址,請注明出處:http://en.pswp.cn/news/247835.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

內部類的用法

第十章 內部類 10.1如何定義內部類 如代碼10.1-1 所示 public class Parcel1 {public class Contents{private int value 0;public int getValue(){return value;}} } 這是一個很簡單的內部類定義方式,你可以直接把一個類至于另一個類的內部,這種定義Contents類的方…

在vue項目中使用樹形結構的穿梭框

先看一下最后的效果&#xff1a; 一個基于elementui的穿梭框組件&#xff1a;el-tree-transfer 第一步&#xff1a;安裝組件 npm install el-tree-transfer --save 第二步&#xff1a;寫代碼 // 使用樹形穿梭框組件<tree-transfer :title"title" :from_datafromDa…

導航跳轉后保持選中狀態 jquery高亮當前選中菜單

功能需求&#xff1a; 今天在寫一個站點需要用到在導航菜單點擊鏈接跳轉到新頁面后&#xff0c;高亮當前菜單樣式。 簡單的說&#xff0c;就是我點擊導航菜單中的一個欄目&#xff0c;跳轉到該欄目下&#xff0c;該欄目菜單也同時高亮&#xff08;可以是背景色也可以是背景圖片…

eacharts中國地圖省市區點擊顯示

1.安裝echarts.js 相關模塊 npm i echarts2. 在 main.js 文件中搭建全局 // 引入echarts import echarts from echarts Vue.prototype.$echarts echarts3.vue文件種引入相關文檔 import echarts from "echarts"; import "./china.js"; // 引入中國地圖…

CF2B The least round way(貪心+動規)

題目 CF2B The least round way 做法 后面\(0\)的個數&#xff0c;\(2\)和\(5\)是\(10\)分解質因數 則把方格中的每個數分解成\(2\)和\(5\)&#xff0c;對\(2\)和\(5\)求兩邊動規&#xff0c;得出最小值\(ansmin(num_2,num_5)\) 我們貪心地選擇最小值所對應的\(2\)或\(5\)&…

JS 中的return false的作用

在大多數情況下,為事件處理函數返回false,可以防止默認的事件行為. Return False 就相當于終止符,終止默認的事件行為&#xff0c;反之,Return True 就相當于執行符,執行終止默認的事件行為。 在js中return false的作用一般是用來取消默認動作的。比如你單擊一個鏈接除了觸發你…

中英翻譯(基于百度翻譯)

先來看效果圖 只做了簡單的在線翻譯&#xff0c;語音翻譯和圖片翻譯都要錢&#xff0c;哈哈 市面上有名氣的翻譯公司就是有道和百度了&#xff0c;有道嘗試了一下&#xff0c;分為API和SDK兩種&#xff0c;但是demo下載下來跑不了 百度的就是API&#xff0c;也很簡單&#xff0…

Vue中使用input簡易的上傳圖片

<div class"boximg"><div class"topimg"><!-- <img :src"filePath" width"200px" height"170px" /> --></div><div class"botimg" click"imgClick()">上傳logo<…

jQuery選擇器之層級選擇器

文檔中的所有的節點之間都是有這樣或者那樣的關系。我們可以把節點之間的關系可以用傳統的家族關系來描述&#xff0c;可以把文檔樹當作一個家譜&#xff0c;那么節點與節點直接就會存在父子&#xff0c;兄弟&#xff0c;祖孫的關系了。 選擇器中的層級選擇器就是用來處理這種關…

文件 圖片 上傳 及少許正則校驗

文件 & 圖片 上傳 及少許正則校驗 <template><div style"padding: 20px"><Row><Col span"24"><div><CFlex type"flex" justify"space-between" align"midlle"><div class"…

bootstrap-table.js如何根據單元格數據不同顯示不同的字體的顏色

在bootstrap-table.js里面列屬性 formatter就是用來格式化單元格的&#xff0c;其默認值是undefined 類型是function&#xff0c;function(value, row, index), value&#xff1a;該cell本來的值&#xff0c;row&#xff1a;該行數據&#xff0c;index&#xff1a;該行序號&am…

SVN_06導入項目文檔

把這個項目的文檔遷入到SVN Server上的庫中 【1】首先右鍵點擊projectAdmin目錄&#xff0c;這時候的右鍵菜單例如以下圖看到的&#xff1a;選擇copy URL toCLipboard,就是復制統一資源定位符&#xff08;URL&#xff09;到剪貼板中 https://KJ-AP01.中國.corpnet:8443/svn/pro…

實現省市二級聯動效果

實現效果&#xff1a; 代碼&#xff1a; <template><div class"main_tableau"><div class"page_title">百城精算編輯</div><CFlex type"flex" justify"space-between"><div style"margin-top…

jquery操作select(取值,設置選中)

jquery操作select(增加&#xff0c;刪除&#xff0c;清空) http://huapengpeng1989412.blog.163.com/blog/static/58828754201342841940720/ jQuery獲取Select選擇的Text和Value: 123456789$("#select_id").change(function(){//code...}); //為Select添加事件&am…

手機驗證碼獲取

<el-form-item label"短信驗證碼" required><el-input v-model"ruleForm.verificationcode" placeholder"請添加驗證碼"><el-button v-if"isdisabled" slot"suffix" style"color:#409EFF;" type&…

關于RGB屏調試的一些知識(轉)

關于RGB屏調試的一些知識轉載于:https://www.cnblogs.com/LittleTiger/p/10983212.html

在bootstrap table中使用Tooltip

//偏好主題function preferenceFormatter(value, row, index) {var nameString "";if (value.length > 6) {nameString value.substring(0,6) ...;} else{nameString value;}return [<a href"#" data-toggle"tooltip" title value >…

實現值兩者之間添加 , 、 | 等字符

展示效果&#xff1a; <span v-for"(item, index) in projectData.bdOwnerList" :key"index"><span style"white-space: nowrap">{{ item.userName }}<spanv-if"projectData.bdOwnerList.length - 1 ! index"style&qu…

spring-cloud搭建

1、myApplicaion 啟動服務類上層必須有一層包 2、報錯 com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect 或者com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known…

JS ===和==區別

這是一種隱式類型轉換 var a 12; var b 12; alert(a b);//先把兩邊的轉換成一樣的&#xff0c;再進行比較 。結果會返回true alert(a b);//不轉換兩邊類型&#xff0c;直接比較,結果返回false