function 執行環境 與 IIFE 與 閉包 與 模組

function 執行環境 與 IIFE 與 閉包 與 模組

js 解析方式:陳述式 和 表達式

js 引擎解析方式: 會先搜尋 function 關鍵字,為行開頭、或在分號後面時,會直接在記憶體中建立函式,為陳述式。 再上到下掃描,遇到var讀到該行,才會建立函式位置,為表達式。


// 陳述式
function hi (){ ... }
// 呼叫 函式名稱 + ()
hi()

// 表達式:為「匿名函式」賦值給變數,變數會指引到 function 儲存位置。
var hoo = function(){ ... }
// 呼叫 變數名稱 + ()
hoo()

資料型態:js 中,任何東西都是物件,function Object

查看物件值:可以 console.log 該物件名稱, 名稱記著「地址」,去地址找到物件「值」。

console.log 一個 function 名稱, 會印出整個 function Object;

但 function 物件,有幾個特殊的屬性:

  • function name
  • function code block:執行 code。
  • () 來帶參數、執行函式。

若為「陳述式」則是特殊屬性的 function name + ()。 若為「表達式」,會是那個 var 變數名稱 + ()

// 一個表達式:程式碼解析到該行,才建立函式、建立後立刻執行。
var hoo = function(n){
return 30 + n;
}()
// hoo 會得到 30+n 後的值:

// 匿名函式如何執行:
(function(){ ... }())
// 裝成「表達式」,否則執行 js 會產生語法錯誤

閉包

.js 中允許「表達式」存在那裡,不做事,也不會回傳錯誤。 但 function 關鍵字,若出現在一行開頭、; 後第一個字, 會被判斷為一「 funtion 陳述式」,被要求後面接 function 名稱, 不可是匿名的,否則會出現語法錯誤

() 是運算子,在 js 中認為 () 為「表達式」, 所以 ( function ... ) 會被判定為一個表達式的存在, 這樣我們讓 function 像其他值一樣,作為表達式存在

IIFE() 包住,可以在 js 執行時不報語法錯誤。 function 執行時,建立了「執行環境」並「生成了」相關的變數, 是一個 閉包結構,就像模組化。

node 模塊 ??

檔案 hello.js:

var s = 'Hello'; // 全域的
var name = 'world';

function greet(name) {
console.log(s + ' ' + name + '!');
}

檔案 hello.js node 會轉為這樣執行:

(function (module) {
var s = 'Hello'; // 閉包
var name = 'world';
function greet(name) {
console.log(s + ' ' + name + '!');
}
module.exports = greet;
})(module);

module.exports:????

http://jsbin.com/zisevaj/edit?js,console


// Node 准备了一个变數 (#hello) module
var module = {
id: 'hello',
exports: {}
};

// Node load 函式,
// 用 `load()` 為 (#hello) `module` 新增 hello.js 中的 `greet` 方法,
var load = function (module) {
// ----------------------- hello.js code
function greet(name) {
console.log('Hello, ' + name + '!');
}
// `module` 是 `load()` 傳入的,故 hello.js 可以讀到
module.exports = greet;
// ----------------------- # hello.js code
// 傳出 (#hello) module.exports = greet 方法
return module.exports;
};

// 將此方法 (#hello) module.exports 存到 exported 變數中
var exported = load(module);

// Node 会把 module 变量保存到某个地方。
save(module, exported);

由于 Node 保存了所有导入 load() 的 (#hello) module 当我们用 require() 获取 (#hello) module 时, Node 返回这个 module 的 exports 变量,

var greet = require('./hello');

这样,另一个模块就顺利拿到了模块的输出

results for ""

    No results matching ""