# 第四章 函式
- 函式 用于指定物件的行為 一組陳述句 javascript 基礎模塊單元 作用: 代碼復用 資訊隱藏 組合呼叫
- javaScript 中 Math 物件 1. Math.ceil() 回傳大于或等于一個給定數字的最小整數(向上取整) console.log(Math.ceil(6.6)); // 7 2. Math.floor() 回傳小于或等于一個給定數字的最大整數(向下取整) console.log(Math.floor(6.6)); // 6 3. Math.max() 回傳一組數中的最大值 console.log(Math.max(1, 2, 3)); // 3 // 在陣列中應用 console.log(Math.max.apply(null, [1, 2, 3])); // 3 // 利用了apply的傳參特性 console.log(Math.max(...[1, 2, 3])); // 3 // 利用了 ES6 Spread 運算子 4. Math.min() 回傳零個或多個數值的最小值 與 Math.max() 函式一樣使用 5. Math.random() 回傳一個 0 到小于 1 的浮點數 6. Math.round() 回傳一個數字四舍五入后最接近的整數 7. Math.sqrt() 回傳一個數的平方根
- 4.1 函式物件 1. 物件 "名/值"對集合 擁有一個連到原型物件的隱藏連接 2. 物件字面量的物件 連接 object.prototype 函式物件 連接 Function.prototype (該原型物件連接object.prototype) 3. 函式創建時的兩個隱藏屬性 函式背景關系 實作函式行為的代碼 4. 函式物件創建時 擁有 prototype 屬性 與隱藏連接 Function.prototype 不同 值(函式物件) 擁有 constructor 屬性
- 4.2 函式字面量 1. 包括四個部分: function 函式名(省略為匿名函式) (引數) {陳述句} 2. 閉包(javaScript表現力的根基) 通過函式字面量創建的函式物件包含一個連到外部背景關系的連接
- 4.3 呼叫 1. 函式呼叫時除接收宣告定義的形參外還接收 this 和 arguments 兩個引數 (1) this 值取決于呼叫的模式 (2) 實參個數與形參不匹配 不會導致運行時錯誤 實參過多 超出引數值被忽略 實參過少 缺失值被 undefined 替代 引數值不會進行型別檢驗 2. javascript 呼叫模式 (1) 方法呼叫模式 方法 函式被保存為物件一個屬性 var myObj = { value: 0, increment: function (inc) { this.value += typeof inc === 'number' ? inc : 1; } } myObj.increment() document.writeln(myObj.value) // 1 myObj.increment(2) document.writeln(myObj.value) // 3 (2) 函式呼叫模式 - 當一個函式不是當做方法使用,而是被當做函式來使用時,其 this 指向全域物件,由此我們就需要定義一個變數并把它賦值為 this,否則就無法實作所需要的功能 - 內部函式中的this仍然指向的是全域物件,即window,這里普遍被認為是JavaScript語言的設計錯誤,因為沒有人想讓內部函式中的this指向全域物件,一般的處理方式是將this作為變數保存下來,一般約定為that或者self
// 定義一個 that,在 helper 函式呼叫前,把 this 賦值給that,再呼叫時 this 指向 double // 若不定義 that 的話, helper 函式的 this 指向全域物件 myObj.double = function () { var that = this // console.log(that) // 1 3 // console.log(that.value) var helper = function (){ // console.log(that.value) // 3 that.value = add(that.value, that.value) }
helper() // 以函式的形式呼叫 helper // console.log(helper()) // undefined }
// 以方法的形式呼叫 double myObj.double() // undefined console.log(myObj.value) // 6
(3) 構造器呼叫模式 javaScript 基于原型繼承的語言 可繼承屬性 無類別的
var Quo = function (string) { // 建構式 this.status = string }
Quo.prototype.get_status = function () { // 方法 return this.status }
// 一個函式帶上 new 呼叫,那么將創建一個連接到該函式 的 prototype 成員的新物件,同時 this 也會系結到這個新物件上 var myQuo = new Quo("confused") // 創建實體,this 系結到 myQuo console.log(myQuo.get_status()) // confused
(4) apply呼叫模式 javascript 函式式面向物件編程語言 函式有方法 apply 方法 構建一個引數陣列,呼叫函式 接收兩個引數 第一個是將被系結給 this 的值 第二個是引數陣列
var array = [5, 4] var sum = add.apply(null, array) console.log(sum) // 9
四種模式的區別: 初始化關鍵引數 this 上存在差異
- 4.4 引數 1. 函式被呼叫時會得到一個引數 arguments 陣列(函式可訪問它被呼叫時傳遞的給它的引數串列) 2. 語言的一個設計錯誤 arguments 并不是一個真正的陣列 "類似陣列(array-like)"物件 擁有屬性 但缺少所有陣列方法
- 4.5 回傳 1. return陳述句 執行時函式回傳不再執行余下陳述句 2. 函式若沒有指定回傳值則回傳undefined 3. 函式以前綴加 new 的方式呼叫則回傳 this(該新物件)
- 4.6 例外 例外 干擾程式正常流程的非正常的事故 一個 try 陳述句只會有一個將捕獲所有例外的 catch 代碼塊
var numAdd = function(a, b) { if (typeof a !== 'number' || typeof b !== 'number') { throw { // 拋出一個 exception 物件,傳遞到 catch 從句 name: 'typeError', message: 'add needs numbers' }; } return a + b }
var try_it = function () { try { // 拋出一個例外,控制權跳到它的 catch 從句 numAdd('seven') } catch (e) { console.log(e.name + ': ' + e.message) } }
try_it() // typeError: add needs numbers
- 4.7 給型別增加方法 通過給 Function.prorotype 增加方法來使得該方法對所有函式可用 Function.prototype.method
- 4.8 遞回 javascript 不提供尾遞回優化,深度遞回函式可能會因為回傳堆疊溢位而運行失敗
// 漢若塔問題 var hanoi = function (disc, src, aux, dst) { if (disc > 0) { hanoi(disc - 1, src, dst, aux) console.log('move disc ' + disc + ' from ' + src + ' to ' + dst) hanoi(disc - 1, aux, src, dst) } } hanoi(3, 'src', 'aux', 'dst') // 結果 // move disc 1 from src to dst // move disc 2 from src to aux // move disc 1 from dst to aux // move disc 3 from src to dst // move disc 1 from aux to src // move disc 2 from aux to dst // move disc 1 from src to dst
- 4.9 作用域 控制著變數與引數的可見性和生命周期 減少名稱沖突 提供自動記憶體管理 C語言語法的語言 塊級作用域 javaScript 擁有函式作用域(定義在函式中的引數和變數在函式外部是不可見的,在一個函式中的任何位置定義的變數在函式中的任何地方都是可見的) 好處:內部函式可以訪問定義它們外部函式的引數和變數(除 this 和 arguments)
- 4.10 閉包 內部函式擁有比它的外部函式更長的生命周期 閉包:函式可以訪問它被創建時所處的背景關系環境 內部函式能訪問外部函式的實際變數而無需復制
var quo = function (status) { return { get_status: function () { return status } } }
// 回傳包含 get_status 方法的一個新物件 // 該物件的一個參考保存在 myQuo 中 // 即使 quo 已經回傳,get_status 方法仍然享有訪問 quo 物件 status 屬性的特權 // get_status 方法不是訪問該引數的一個拷貝,其訪問的就是該引數本身 var myQuo = quo("amazed") console.log(myQuo.get_status()) // amazed
- 4.11 回呼 用于異步請求,提供一個當服務器回應到達時被呼叫的函式 客戶端不會被堵塞
- 4.12 模塊 1. 模塊 由函式和閉包構建 一個提供介面卻隱藏狀態與實作的函式或物件 2. 模塊模式一般形式 - 一個定義私有變數和函式的函式 - 利用閉包創建可以訪問私有變數和函式的特權函式 - 回傳特權函式或把它們保存到一個可訪問到的地方
- 4.13 級聯 一些設定或修改物件的某個狀態不回傳任何值的方法,若使其回傳 this,就需要啟用級聯的方式 一個級聯中可以在一條陳述句中依次呼叫同一個物件的很多方法
- 4.14 套用 將函式與傳遞給它的引數相結合去產生出一個新的函式 var add = add.curry(1) function.method('curry', function () { })
## 本章難點(解答見其他文章) 1. 閉包 2. javascript 呼叫模式 (函式呼叫模式、Apply呼叫模式) 3. javascript 關鍵字 this 4. 作用域 5. 模塊
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/180426.html
標籤:其他
