1. 程式人生 > >《JavaScript語言精粹》學習筆記——4.函式

《JavaScript語言精粹》學習筆記——4.函式

前言

函式用於指定物件的行為,是JavaScript的基礎單元。所謂程式設計,就是將一組需求分解為一組函式和資料結構的功能。

1、函式物件

JavaScript中的函式就是物件。每個函式在建立時會附加兩個隱藏的屬性:函式的上下文和實現函式呼叫的程式碼。

函式可以像其他的值一樣被使用,可以被儲存在另一個物件中,可以作為引數傳遞,可以返回函式,還可以有方法,唯一不同的是可以被呼叫。

2、函式字面量

通過函式字面量建立函式:

var add = function (a, b) {
     return a + b;
}

函式由以下幾個部分組成:

function保留字;

函式名,function後面跟函式名,

可省略(省略函式名的稱為匿名函式);

引數,圓括號中的引數;

函式主體,花括號裡面的一組語句,在函式呼叫時執行。

3、呼叫

函式在呼叫時接收兩個附加的引數:this和argument。函式呼叫符是函式值表示式後的一對圓括號。

argument是實際引數,當實際引數與形式引數個數不匹配時,程式不會報錯。實際引數值過多,超出的引數會被省略,實際引數值過少,缺少的引數會被替換為undefined。

函式有四種呼叫方式:方法呼叫模式、函式呼叫模式、構造器呼叫模式、apply呼叫模式。

4、方法呼叫模式

函式作為物件的一個屬性時,稱為方法。當一個方法被呼叫時,this繫結為該物件。

var myObject = {
     value: 0,
     increment: function (inc) {
           this.value + = typeof inc === 'number' ? inc : 1;
     }
}
<pre name="code" class="javascript">myObject.increment(2);

5、函式呼叫模式

一個函式不作為物件的屬性時,就是函式呼叫方式。

此模式下,this繫結到全域性物件。有時引用內部函式時,會帶來不必要的錯誤,解決方法將this傳遞給另一個變數。

var sum = add(3, 4);
var that =  this;
6、構造器呼叫模式

構造器呼叫模式,使用new來呼叫一個函式,建立一個連線到該函式prototype成員的新物件。

函式建立的目的就是以這種方式呼叫,稱為構造器函式。構造器函式第一個字母需要大寫。如果沒有使用new來呼叫構造器函式不會報錯,因此不推薦使用構造器呼叫模式。

7、Apply呼叫模式

函式具有apply方法,可以指定this的值。

apply接收兩個引數,第一個引數是this的值,第二個引數是傳遞的引數陣列。

8、引數

函式呼叫時,會得到一個引數——arguments陣列,這個陣列是呼叫函式時傳遞進來的引數列表,包括多餘的引數。

arguments不是一個真正的陣列,僅包含length屬性,沒有其他任何陣列的方法。

9、返回

return可以提前使函式提前返回。

一個函式總會返回一個值,如果沒有指定返回值,則返回undefined。

使用new字首呼叫函式,返回值不是一個物件,則返回this(該新物件)。

10、異常

JavaScript 提供了一套異常處理機制。

throw 語句可以中斷函式的執行,丟擲的 exception 物件具有兩個屬性,異常型別 name 屬性和描述性的 message 屬性。

try...catch 語句中,如果在 try 中遇到異常,程式會跳到 catch 中繼續執行。一個 try 語句只有一個捕獲異常的 catch 程式碼塊。

11、擴充型別的功能

JavaScript允許給語言的基本型別擴充功能。給Object.propertype新增方法,讓該方法對所有物件都可用。這種方式同樣對函式(Function)、陣列(Array)、字元(String)、數字(Number)、正則表示式和布林值同樣適用。

舉例,給Function.propertype增加一個method方法,下次再給物件增加方法時,可用省略propertype。

Function.propertype.method = function (name, func) {
       this.propertype[name] = func;
       return this;
}
<pre name="code" class="javascript">String.method('trim', function (){
   return this.replace(/^s+|\s+$/g, '');
})<span style="font-family: Arial, Helvetica, sans-serif;">;</span>
12、遞迴

遞迴函式就是直接或間接呼叫自身的一種函式。

一個問題能分解為一組相似的問題,每個問題都能用一個簡單的方法去解決,遞迴就是呼叫自身去解決它的子問題。

舉例,遍歷DOM中的所有節點,每個節點都執行函式func。

var walk_the_DOM = function walk(node, func) {  
      func(node);                    // 從節點node開始
      node = node.firstChild;        //<span style="font-family: Arial, Helvetica, sans-serif;">找到下一個子節點</span>
      while (node) {
           walk(node, func);         //對子節點執行函式
           node = node.nextSibling;  //找到下一個子節點
      }
}
尾遞迴,會返回自身呼叫的結果,是一種在函式的最後執行遞迴呼叫語句特殊形式的遞迴。(個人理解:尾遞迴是在遞迴的最後呼叫一個特殊的語句,而不同於找不到子節點或堆疊溢位而結束遞迴。)

尾遞迴優化,函式返回自身遞迴呼叫的結果,呼叫過程會被替換成一個迴圈,可以顯著提高速度。

13、作用域

作用域控制著變數與引數的可見性及生命週期。

JavaScript 支援函式作用域,在函式中的引數和變數在函式外部是不可見的,在一個函式的內部任何位置定義的變數,在該函式內部任何地方都可見。作用域的好處是內部函式可以訪問它們的外部函式的引數和變數(除了this和arguments)。

14、閉包

內部函式擁有比它的外部函式更長的生命週期。內部函式可以訪問它被建立時所處的上下文環境,這被稱為閉包

15、回撥

網路上的同步請求時間過長會導致客戶端進入假死狀態,發起非同步請求,提供一個當伺服器的響應到達時隨時出發的回撥函式,客戶端就不會阻塞。

16、模組

使用函式和閉包來構造模組。

模組模式利用了函式作用域閉包來建立被繫結物件與私有成員的關聯。

模組模式的一般形式是:一個定義了私有變數和函式的函式;利用閉包建立可以訪問私有變數和函式的特權函式;最有返回這個特權函式,或者把它們儲存到一個可訪問到的地方。

var serial_marker =  function (argument) {
		var prefix = '';  // 私有變數
		var seq = 0;      // <span style="font-family: Arial, Helvetica, sans-serif;">私有變數</span>

		return {
			set_prefix: function (p) {
				prefix = String(p);
			},
			set_seq: function (s) {
				seq = s;
			},
			gensym: function () {
				var result = prefix + seq;
				seq += 1;
				return result;
			}
		}
	}

	var seqer = serial_marker();
	seqer.set_prefix('Q');
	seqer.set_seq(1000);
	var unique = seqer.gensym();

	document.writeln('1.   unique: '+unique+'<br/>');  // 1.    unique: Q1000

	                                                   // 即使增加了新的方法,不能更改私有變數的值
	seqer.newset_prefix = function (p) {
		prefix = String(p);
	}
	seqer.newset_prefix('W')                          //<span style="font-family: Arial, Helvetica, sans-serif;"> 即使增加了新的方法,不能更改私有變數的值</span>


	var unique = seqer.gensym();
	document.writeln('2.   unique: '+unique);         // 2.     unique: Q1001
17、級聯

有一些方法是沒有返回值的,比如一些修改或者設定物件的某個狀態的方法,不需要返回值。可以讓這些方法可以返回 this 而不是 undefined ,就可以啟用級聯。這些方法每一個都返回該物件,每次返回的結果都可以被下一次呼叫。

getElement('myBoxDiv')
     .move(350, 150)
     .width(100)
     .height(100)
     .color('red')
18、柯里化

呼叫柯里化方法生成新函式,呼叫新函式時,是返回呼叫原始函式的結果,傳遞呼叫柯里化方法的引數加上呼叫新函式的引數。

柯里化方法的新函式呼叫 = 呼叫原始函式 + ( 柯里化方法的引數 + 新函式呼叫引數 )

Function.method('curry', function () {
		var slice = Array.prototype.slice,
			args = slice.apply(arguments),   // arguments不是真正的陣列,除length方法外無陣列的其他方法
			                                 // args現在是真正的陣列,有陣列的方法
			that = this;
		
		// 返回柯里化新函式
			
		return function () {

			// 新函式包含原函式呼叫
			// 和柯里化函式時的引數
			// 和呼叫新函式時的引數
			
			return that.apply(null, args.contact(slice.apply(arguments)))  
		};
	});
19、記憶

函式將先操作的結果記錄在某個物件裡,避免無謂的重複運算,這種優化被稱為記憶。

相關推薦

JavaScript語言精粹學習筆記——4.函式

前言 函式用於指定物件的行為,是JavaScript的基礎單元。所謂程式設計,就是將一組需求分解為一組函式和資料結構的功能。 1、函式物件 JavaScript中的函式就是物件。每個函式在建立時會附加兩個隱藏的屬性:函式的上下文和實現函式呼叫的程式碼。 函式可以像其他的值一

JavaScript語言精粹》--第4章:函式

/* 函式物件 JS中的函式就是物件,函式物件連線到Function.prototype,而Function.prototype物件本身連線到Object.prototype 每個函式在建立時會附加兩個隱藏屬性: 函式物件數的上下文 實現函式行為的程式碼

JavaScript語言精粹筆記(內附《JavaScript語言精粹》百度雲下載連結)

章節:3.4 引用 【P22(頁碼)】 知識點:物件通過引用來傳遞,它們永遠不會被傳遞 var a_obj={a:1}; var b_obj=a_obj;//b_obj是a_obj的引用 b_obj.a=2; console.log(a_obj.

JavaScript 小白學習筆記(4)----(詳解)json格式的資料

json格式的資料:    <1>一般都是成對出現的, 是鍵值對。    <2>json也是一個物件,無論是鍵還是值,都是用雙引號引起來的。    下面的json["屬性名"]相

Python3學習筆記4-函式,全域性變數&區域性變數,內建函式

1 Functions Keyword, Function name, parameters and body. 函式都以關鍵詞def開頭,然後是函式名,需要傳遞的引數,函式體。最後一般會返回值。 早上的for,while筆記中有 Prime Number

JS語言精粹學習筆記--物件字面量

物件 JS的簡單資料型別包括:數字、字串、布林值(true/false)、null值和undefined,其他所有的值都是物件。數字、字串、布林值貌似物件,因為他們擁有方法,但他們是不可變的。JS中的物件是可變的鍵控集合(keyed collection)。在JS中,陣列、

JavaScript語言精粹學習筆記——附錄B.糟粕

作者的意思是儘量棄之不用的部分。 1、== == 和 != 運算子只有在兩個運算時型別一致時,才能做出正確判斷,如果兩個運算數是不同型別,會強制轉換值的型別,有時會得到正確的結果,有時不會,因此永遠不要使用這個運算子,始終使用 === 和 !== 運算子,可以減少錯誤。 2

【幹貨】JavaScript DOM編程藝術學習筆記4-6

ext 屬性節點 另一個 機器 rep lin bsp 每次 增加 四、案例研究:JavaScript圖片庫 js: function showPic(whichpic){ //取得鏈接 var source=whichpic.getAttribute("hr

JavaScript語言精粹》讀書筆記——給類型增加方法一節的疑問

讀書 ceiling lac 方法 formal ger 公式 num turn 最近,在學習《JavaScript語言精粹》這本書,發現譯者雖然有很好地翻譯文章,卻沒有對文中有疑問的地方進行改正或加以註釋。我接觸JavaScript只有一年左右,可能無法很好的理解這門語

Arcgis api for javascript學習筆記(4.6版本) - 二維MapView中的FeatureLayer顯示標註

meta AS dojo each 自己 round updating 完成後 graph 4.6版本api的FeatureLayer中有提供 labelsVisible 和 labelingInfo 兩個屬性,設置這兩個屬性可以實現顯示將屬性中某個字段作為標註。但是這兩個

北京大學Cousera學習筆記--4-計算導論與C語言基礎--計算機的基本原理-程序運行的基本原理

運行程序 控制 部分 byte 輸入 分類 技術 表示 在一起 已知:電路能完成計算 怎麽計算:設計好很多個原子電路,需要的時候就把他們臨時組裝在一起--ENIAC 升級:馮諾依曼-EDVAC(現在的計算機都是)   1、通過某種命令來控制計算機。讓計算機按照這種命令來運行

C語言實例解析精粹學習筆記——18

static abcd str 工作 結果 size put cls 字符 《C語言實例解析精粹》中編譯環境采用的是Turbo C 2.0。但是這個編譯器年代久遠,較新的編譯器對書中的某些例子支持不好,在學習的時候同時做一些筆記。 實例18:將一個無符號整數轉換為任意d進制

C語言實例解析精粹學習筆記——19

sca sta tran int nbsp unsigned define col 表示 實例19:判斷正整數n的d進制表示形式是否是回文數(順著看和倒著看相同的數)。 主要思路: 一種方法:將正整數n數轉換成d進制的數,逐個比較首尾對應數字,判斷是否為回文數。 另一種方法

JavaScript核心技術學習筆記4)——事件基礎

() block 發生 UNC spa on() strong 1.2 type 事件基礎 一、事件 事件是什麽? 舉個例子,我們在點擊一個按鈕時,會彈出一個對話框。其中,“點擊”就是一個事件,“彈出對話框”就是我們在點擊這個事件後發生的動作。 在JS中,一個事件應該有三個

C語言實例解析精粹學習筆記——29

r+ 函數 復制 printf bsp 不同 getch 多余 個數 題目: 將字符行內單字之間的空格平均分配插入到單字之間,以實現字符行排版。也就是輸入一個英文句子,單詞之間的空格數目不同,將這些空格數平均分配到單詞之間,重新輸出。 代碼如下(是原書中配套

C語言實例解析精粹學習筆記——32

組合 pri 結構體指針 name ber ESS tdi 筆記 string 實例32:   編制一個包含姓名、地址、郵編和電話的通訊錄輸入和輸出函數。 思路解析:   1、用結構體來完成姓名、地址、郵編和電話的組合。   2、結構體指針的使用。   3、malloc的使

Javascript高階程式設計學習筆記(7)—— 函式

前幾天有事耽擱了,今天繼續更新 今天的主要內容是JS中的函式 這一篇主要講函式的定義等內容,至於變數提升、執行環境、閉包、記憶體回收等內容在後面講,高玩們可以不用看下面的正文了。   函式 首先來講,函式對於任何程式語言都是一個十分核心的概念。 Js中的函式通過function關鍵字來宣

(C/C++學習筆記)4.C++類中的虛擬函式表Virtual Table

1 #include <iostream> 2 using namespace std; 3 4 class base 5 { 6 public: 7 virtual void f(){cout<<"base::f()"<<endl;}

R語言學習筆記——melt()函式之整齊資料

R語言學習筆記(二) melt()函式 melt(data,id.vars,measure.vars,variable.name=“variable”,…,na.rm=FALSE,value.name=“value”,factorsAsStrings=TRUE)

C語言學習筆記---malloc函式詳解

                                                                                            malloc函式詳解 一、malloc函式標頭檔案: #include<stdli