成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

《JavaScript高級程序設(shè)計》(第3版)讀書筆記 第5章 引用類型

zero / 2474人閱讀

摘要:引用類型的值對象是引用類型的一個實例。引用類型是一種數(shù)據(jù)結(jié)構(gòu),用于將數(shù)據(jù)和功能組織在一起。對數(shù)組中的每一項運行給定函數(shù),如果該函數(shù)對任一項返回,則返回。組零始終代表整個表達式。所以,使用非捕獲組較使用捕獲組更節(jié)省內(nèi)存。

引用類型的值(對象)是引用類型的一個實例。

引用類型是一種數(shù)據(jù)結(jié)構(gòu),用于將數(shù)據(jù)和功能組織在一起。它同行被稱為,但這種稱呼并不妥當,盡管ECMAScript從技術(shù)上講是一門面向?qū)ο蟮恼Z言,但他不具備傳統(tǒng)的面向?qū)ο笳Z言所支持的接口等基本結(jié)構(gòu)。

引用類型有時候也被稱為對象定義

關(guān)于typeof中的"object"和Object()構(gòu)造函數(shù)的個人理解:

typeof操作符返回的"object"值指的是數(shù)據(jù)類型

在new Object()中"Object"表示的是數(shù)據(jù)結(jié)構(gòu)(引用類型),所以new Object()返回的是基于Object引用類型的一個實例

typeof返回的"function" 和 Function()構(gòu)造函數(shù) 同理

Object類型

創(chuàng)建對象的方法一個new Object(),另一個是對象字面量表示法

字面量表示法的最后一個屬性不能添加逗號,這樣會在IE7以前和Opera中導(dǎo)致錯誤

屬性名會自動轉(zhuǎn)換為字符串

屬性名中包含關(guān)鍵字、保留字會報錯

通常,除非必須使用變量來訪問屬性,否則我們建議使用點表示法

// 這里所有的屬性名都會自動轉(zhuǎn)為字符串
var person = {
    "name": "Nicholas",
    age: 29,
    5: true
}

// 不會報錯,但這個屬性不能使用person.name的方式
person["first name"] 
Array類型

創(chuàng)建數(shù)組的基本方式有兩種。使用Array構(gòu)造函數(shù),字面量表示法

var colors = new Array();
var colors = new Array(20);                        // 傳入一個數(shù)值 創(chuàng)建一個length為20的空數(shù)組
var colors = new Array("red");                     // 傳入非數(shù)值 因此為元素的數(shù)組
var colors = new Array("red", "blue", "green");
var colors = ["red", "blue", "green"];
colors.length = 2;
alert(colors[2]);        // undefined
var colors = ["red", "blue", "green"];
colors[colors.length] = "black";
colors[colors.length] = "brown";            // 添加新項
var colors = ["red", "blue", "green"];
colors[99] = "black";
alert(colors.length);            // 100 位置3到98的值都不存在,都將返回undefined
檢測數(shù)組

對于一個網(wǎng)頁或者一個全局作用域而言,使用instanceof操作符就能得到結(jié)果

if (value instanceof Array) {
    ...
}

如果網(wǎng)頁中包含多個 框架,實際上就存在兩個以上的不同全局執(zhí)行環(huán)境,從而存在兩個以上不同版本的Array構(gòu)造函數(shù),為此ECMAScript5新增了Array.isArray()方法.IE9+,Firefox4+,safari5+,Opera10.5+ Chrome

if (Array.isArray(value)) {
    ...
}
轉(zhuǎn)換方法

所有對象都據(jù)歐toLocaleString(),toString(),valueOf()方法。toString()返回由逗號拼接的字符串,valueOf()返回的還是數(shù)組

join() 如果傳入undefined,默認逗號分隔,IE7以前的版本會錯誤的以undefined分隔

如果數(shù)組中某一項是null或者undefined,那么該值在join(),toLocaleString(),toString(),valueOf()方法返回的結(jié)果以空字符串表示

棧方法

棧是一種LIFO(Last-In-First-Out 后進先出)的數(shù)據(jù)結(jié)構(gòu)。而棧中的插入(推入)和移除(彈出),只發(fā)生在一個位置——棧的頂部。ECMAScript為數(shù)組專門提供了push()和pop()方法

var colors = ["red", "blue", "green"];
var item = colors.pop();
alert(colors.length);        //    2
alert(item)                  //    “black”取得最后一項
隊列方法

隊列數(shù)據(jù)結(jié)構(gòu)的訪問規(guī)則是FIFO(First-In-First-Out 先進先出)

shift()方法能移出數(shù)組的第一項并返回該項,結(jié)合使用shift()和push()方法可以實現(xiàn)

unshift()方法能在數(shù)組前端添加任意個項并返回新數(shù)組的長度, IE7以下的版本總是返回undefined,IE8在非兼容模式下會返回正確的長度值

var colors = ["red", "blue", "green"];
colors.push("black");
var item = colors.shift();
console.log(colors);        //  ["blue", "green", "black"]
console.log(item)                  //    “red”取得最后一項
var colors = new Array();
colors.unshift("red", "green");        // 推入兩項
console.log(colors.length);            // 2
重排序方法

數(shù)組存在兩個直接重排序的方法 reverse() sort()

reverse()直接返回將原數(shù)組倒序排列

sort() 調(diào)用每項的toString()轉(zhuǎn)型方法,按照升序排列,即使數(shù)組中的每一項都是數(shù)值,sort()方法比較的也是字符串

sort()可傳入一個比較函數(shù),比較函數(shù)接受兩個參數(shù),如果第一個參數(shù)應(yīng)該位于第二個之前

var values = [0, 1, 5, 10, 15];
values.sort();
console.log(values);         // 0,1,10,15,5

// 使用比較函數(shù)是sort的最佳使用方式
function compare(value1, value2) {
    if (value1 < value2) {
        return -1;
    } else if (value1 > value2) {
        return 1;
    } else {
        return 0;
    }
}
var values = [0, 1, 10, 15,  5];
values.sort(compare);
console.log(values);         // 0,1,5,10,15

// 對于數(shù)值類型或者其valueOf()方法會返回數(shù)值類型的對象類型
// 可以使用一個更簡單的比較函數(shù)
function compare(value1, value2) {
    return value2 - value1
}
操作方法

concat() 先創(chuàng)建一個數(shù)組副本,再將傳入的元素添加到新數(shù)組的末尾

var colors = ["red", "green", "blue"];
var colors2 = colors.concat("yellow", ["black", "brown"]);

alert(colors); // red,green,blue
alert(colors2);    // red,green,blue,yellow,black,brown

slice()可以接收一個或兩個參數(shù),基于當前數(shù)組創(chuàng)建新數(shù)組,返回指定位置之間的所有項,slice()方法不會影響原數(shù)組

如果slice參數(shù)有一個負數(shù),則用數(shù)組長度加上該數(shù)來確定相應(yīng)的位置

var colors = ["red", "green", "blue", "yellow", "purple"];
var colors2 = colors.slice(1);            //    green,blue,yellow,purple
var colors3 = colors.slice(1,4);          //    green,blue,yellow

splice() 最強大的數(shù)組方法,始終返回一個數(shù)組,該數(shù)組中包含從原始數(shù)組中刪除的項(沒有就返回空數(shù)組)

刪除:可以刪除任意數(shù)量的項,只需指定2個參數(shù):要刪除的第一項的位置和要刪除的項數(shù)

插入:可以向指定位置插入任意數(shù)量的項,只需提供3個參數(shù):起始位置、0(插入操作沒有要刪除的項所以是0)和要插入的項,多個可以傳任意個數(shù)的參數(shù)

替換:可以向指定位置插入任意數(shù)量的項,且同時刪除任意數(shù)量的項,刪除的項數(shù)不必與插入的項數(shù)相等

var colors = ["red", "green", "blue"];
var removed = colors.splice(0, 1);                    // 刪除第一項 removed 為 ["red"]
alert(colors);                                        // ["green", "blue"]

removed = colors.splice(1, 0, "yellow", "orange");    // 從位置1開始插入兩項
console.log(colors);                                  // green,yellow,orange,blue
console.log(removed);                                 // 返回空數(shù)組

removed = colors.splice(1, 1, "red", "purple");       // 插入兩項,刪除一項
console.log(colors);                                  // green,red,purple,orange,blue
console.log(removed);                                 // ["yellow"]
位置方法

數(shù)組有兩個位置方法,都接收兩個參數(shù):要查找的項和(可選)表示查找氣墊位置的索引,返回查找對應(yīng)項的位置,沒有找到返回-1。在比較第一個參數(shù)與數(shù)組中的每一項時,會使用全等操作符;

indexOf() 從開頭(位置0)查找

lastIndexOf() 從末尾開始向前查找

支持的瀏覽器 IE9+, Firefox2+, safari3+, Opera9.5+ Chrome

var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4));            //    3
alert(numbers.lastIndexOf(4));        //    5

alert(numbers.indexOf(4, 4));            //    5
alert(numbers.lastIndexOf(4, 4));        //    3

var person = { name: "Nicholas" };
var people = [{ name: "Nicholas" }];

var morePeople = [people];

alert(people.indexOf(person));            // -1
alert(morePeople.indexOf(person));        // 0 
// 兩個引用類型對象值完全相同,但引用的內(nèi)存地址不同
var a = { name: "obj" }
var b = { name: "obj" }
a == b                    //   false
a === b                    //   false
迭代方法

ECMAScript5位數(shù)組定義了5個迭代方法,每個方法都接收兩個參數(shù):要在每一項上運行的函數(shù)和(可選的)運行該函數(shù)的作用域?qū)ο蟆绊憈his的值。傳入這些方法中的函數(shù)會接收三個參數(shù):數(shù)組項的值,該項在數(shù)組中的位置和數(shù)組對象本身。

every():對數(shù)組中的每一項運行給定函數(shù),如果該函數(shù)對每一項都返回true,則返回true

filter():對數(shù)組中的每一項運行給定函數(shù),返回該函數(shù)會返回true的項組成的數(shù)組

forEach():對數(shù)組中的每一項運行給定函數(shù)。這個方法沒有返回值

map():對數(shù)組中的每一項運行給定函數(shù),返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組。

some():對數(shù)組中的每一項運行給定函數(shù),如果該函數(shù)對任一項返回true,則返回true。

以上方法都不會修改數(shù)組中的包含的值

支持的瀏覽器 IE9+, Firefox2+, safari3+, Opera9.5+ Chrome

歸并方法

ECMAScript5新增了兩個歸并數(shù)組的方法 reduce()和reduceRight()。迭代數(shù)組的所有項,然后構(gòu)建一個最終返回的值

reduce() 從數(shù)組的第一項開始,逐個遍歷到最后

reduceRight() 則從最后一項開始

支持的瀏覽器 IE9+, Firefox3+, safari4+, Opera10.5+ Chrome

var values = [1,2,3,4,5];
// prev 前一項, cur 迭代的當前項
// 第一次執(zhí)行回調(diào)函數(shù),prev是1,cur是2
var sum = values.reduce(function(prev, cur, index, array) {
    return prev + cur;
});
alert(sum);         // 15
Date類型

下面兩行代碼是等價的,Date構(gòu)造函數(shù)會在后臺調(diào)用Date.parse()

不用Date.parse()或Date.UTC() 都是基于系統(tǒng)設(shè)置本地時區(qū)創(chuàng)建的

Date.now() 返回調(diào)用時日期和時間的毫秒數(shù),支持的瀏覽器IE9+, Firefox3+, safari3+, Opera10.5+ Chrome

var someDate = new Date(Date.parse("May 25, 2004"));
var someDate = new Date("May 25, 2004");
// GMT時間200年1月1日午夜零時
var y2k = new Date(Date.UTC(2000, 0));
var y2k = new Date(2000, 0);

// GMT時間2005年5月5日下午5:55:55
var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55));
var allFives = new Date(005, 4, 5, 17, 55, 55);
// Date.now()在不支持的瀏覽器中如下寫法
var start = +new Date();
start           // 返回毫秒數(shù)
typeof start     // "number"
繼承方法

toLocaleString()和toSring()的這一差別僅在調(diào)試代碼時比較有用

valueOf()方法,不返回字符串,返回日期的毫秒表示

var date1 = new Date(2007, 0, 1);        // "January 1 , 2007"
var date2 = new Date(2007, 1, 1);        // "February 1, 2007"

console.log(date1 < date2);             // true
console.log(date1 > date2);             // false
日期格式化方法

toDateString() 特定格式顯示星期幾、月、日和年

toTimeString() 特定格式顯示 時、分、秒和時區(qū)

toLocaleDateString() 特定于地區(qū)格式顯示星期幾、月、日和年

toLocaleTimeString() 特定于地區(qū)實現(xiàn)的格式顯示時、分、秒

toUTCString() 特定于實現(xiàn)的格式UTC日期

日期/時間組件方法

圖表略...

RegExp類型

ECMAScript通過regExp類型來支持正則表達式

每個正則表達式都可帶有一或多個標志(flags)

g:表示全局模式(global),即模式將被應(yīng)用于所有字符串,而非在發(fā)現(xiàn)第一個匹配項時立即停止

i:表示不區(qū)分大小寫(case-insensitive)模式,即在確定匹配項時忽略模式與字符串的大小寫

m:表示多行模式(multiline),即在到達一行文本末尾時還會繼續(xù)查找下一行中是否存在于模式匹配的項

// 匹配字符串中所有“at”的實例
var pattern1 = /at/g;

// 匹配第一個"bat"或"cat",不區(qū)分大小寫
var pattern2 = /[bc]at/i;

// 匹配所有以"at"結(jié)尾的3個字符的組合,不區(qū)分大小寫
var pattern3 = /.at/gi;

模式中使用的所有元字符都必須轉(zhuǎn)義:( [ { ^ $ | ) ? * + . ] }

使用RegExp構(gòu)造函數(shù),兩個參數(shù)都必須是字符串,所有元字符都要雙重轉(zhuǎn)義

// 匹配第一個"bat"或"cat", 不區(qū)分大小寫
var patter1 = /[bc]at/i;

// 匹配第一個"[bc]at", 不區(qū)分大小寫
var pattern2 = /[bc]at/i;

// 匹配所有以"at"結(jié)尾的3個字符的組合,不區(qū)分大小寫
var pattern3 = /.at/gi

// 匹配所有".at",不區(qū)分大小寫
var pattern4 = /.at/gi;
// 使用RegExp構(gòu)造函數(shù),所有元字符都要雙重轉(zhuǎn)義
// 兩個參數(shù)都必須是字符串
var pattern4 = new RegExp(".at", "i");

我們可以使用小括號"()"來指定要重復(fù)的子表達式,然后對這個子表達式進行重復(fù),例如:(abc)? 表示0個或1個abc 這里一 個括號的表達式就表示一個分組 。分組可以分為兩種形式,捕獲組非捕獲組。

捕獲組可以通過從左到右計算其開括號來編號 。例如,在表達式 (A)(B(C)) 中,存在四個這樣的組。組零始終代表整個表達式。之所以這樣命名捕獲組是因為在匹配中,保存了與這些組匹配的輸入序列的每個子序列。在表達式中使用,也可以在匹配操作完成后從匹配器檢索。

編號 項目
0 (A)(B(C))
1 (A)
2 (B(C))
3 (C)

以 (?) 開頭的組是純的非捕獲組(?:Pattern),它不捕獲文本 ,也不針對組合計進行計數(shù)。就是說,如果小括號中以?號開頭,那么這個分組就不會捕獲文本,當然也不會有組的編號。非捕獲組則不會捕獲文本,也不會將它匹配到的內(nèi)容多帶帶分組來放到內(nèi)存中。所以,使用非捕獲組較使用捕獲組更節(jié)省內(nèi)存。

RegExp實例屬性

RegExp的每個實例都具有下列屬性,通過這些屬性可以取得有關(guān)模式的各種信息

global 布爾值 表示是否設(shè)置了g標志

ignoreCase 布爾值 表示是否設(shè)置了i標志

lastIndex 整數(shù) 表示開始搜索下一個匹配項字符位置,從0算起

multiline 布爾值 表示是否設(shè)置了m標志

source 正則表達式的字符串表示,按照字面量形式而非傳入構(gòu)造函數(shù)中的字符串模式返回

var pattern1 = /[bc]at/i;
console.log(pattern1.global);            // false
console.log(pattern1.ignoreCase);        // true
console.log(pattern1.multiline);         // false
console.log(pattern1.lastIndex);         // 0
console.log(pattern1.source);            // "[bc]at"
RegExp實例方法

exec() 專門為捕獲組而設(shè)計的,接收一個參數(shù),即要應(yīng)用模式的字符串,然后返回包含第一個匹配項信息的數(shù)組;或者在沒有匹配項的情況下返回null

返回的數(shù)組雖然是Array的實例,但包含兩個額外的屬性:index和input

index表示匹配項在字符串中的位置

input表示表達式的字符串

即使在模式中設(shè)置了全局標志(g),exec()每次也只會返回一個匹配項,不設(shè)置g的時候,每次都返回第一個匹配項,設(shè)置了g的情況下,每次調(diào)用exec()則都會在字符串中繼續(xù)查找新匹配項

var txt = "mom and dad and baby";
var pattern = /mom( and dad( and baby)?)?/gi;

var matches = pattern.exec(txt);
console.log(matches);            
//    ["mom and dad and baby", " and dad and baby", " and baby", index: 0, input: "mom and dad and baby", groups: undefined]

test() 接收字符串參數(shù),匹配返回true不匹配返回false

var txt = "000-00-0000";
var pattern = /d{3}-d{2}-d{4}/;
if (pattern.test(txt)) {
    alert("The pattern was matched.");
}

toString() toLocaleString() 都會返回正則表達式的字面量,與創(chuàng)建表達式的方式無關(guān)

valueOf() 返回正則表達式本身

RegExp構(gòu)造函數(shù)屬性

RegExp構(gòu)造函數(shù)包含一些屬性,適用于作用域中的所有表達式,并且基于所執(zhí)行的最近一次正則表達式操作而變化

這些屬性分別有一個長屬性名和一個短屬性名(Opera例外,不支持短屬性)

長屬性名 短屬性名 說明
input $_ 最近一次要匹配的字符串。Opera不支持
lastMatch $& 最近一次的匹配項目。Opera不支持
lastParen $+ 最近一次匹配的捕獲組。Opera不支持
leftContext $` input字符串中l(wèi)astMatch之前的文本。
multiline $* 布爾值 表示是否所有表達式都是用多行模式。IE和Opera未實現(xiàn)此屬性
rightContext $" input字符串中l(wèi)astMatch之后的文本。

使用這些屬性可以從exec() test()執(zhí)行的操作中提取更具體的信息

var txt = "this has been a short summer";
var pattern = /(.)hort/g;

// Oper不支持input,lastMatch,lastParen,multiline
// IE不支持multiline
if (pattern.test(txt)) {
    console.log(RegExp.input);                            // this has been a short summer
    console.log(RegExp.leftContext);                      // this has been a
    console.log(RegExp.rightContext);                     // summer
    console.log(RegExp.lastMatch);                        // short
    console.log(RegExp.lastParen);                        // s
    console.log(RegExp.multiline);                        // false
}

短屬性名打斗不是有效的ECMAScript標識符,因此必須通過方括號語法來訪問

var txt = "this has been a short summer";
var pattern = /(.)hort/g;


// Oper不支持input,lastMatch,lastParen,multiline
// IE不支持multiline
if (pattern.test(txt)) {
    console.log(RegExp.$_);                            // this has been a short summer
    console.log(RegExp.["$`"]);                      // this has been a
    console.log(RegExp.["$""]);                     // summer
    console.log(RegExp.["$&"]);                        // short
    console.log(RegExp.["$+"]);                        // s
    console.log(RegExp.["$*"]);                        // false
}

除了上面介紹的幾個屬性之外,還有多達9個用于存儲捕獲組的構(gòu)造函數(shù)屬性:RegExp.$1,RegExp.$2......RegExp.$9

var txt = "this has been a short summer";
var pattern = /(..)or(.)/g;

// 這里創(chuàng)建了一個包含兩個捕獲組的模式,并用該模式測試了一個字符串。
// 即使test()方法只返回一個布爾值,但RegExp構(gòu)造函數(shù)的屬性$1和$2也會被匹配相應(yīng)捕獲組的字符串自動填充
if (pattern.test(txt)) {
    console.log(RegExp.$1);        // sh
    console.log(RegExp.$2);        // t
}
模式的局限性

盡管ECMACScript中的正則表達式功能還是比較完備的,但仍然缺少某些語言所支持的高級正則表達式特性

下面列出了不支持的特性

匹配字符串開始和結(jié)尾A 和 Z 錨 (但支持以插入符號 ^ 和美元符號 $ 來匹配字符串的開始和結(jié)尾)

向后查找(lookbehind) (但完全支持向前查找lookahead)

并集和交集

原子組(atomic grouping)

Unicode支持(耽擱字符串除外, 如 uFFFF)

命名的捕獲組(但支持編號的捕獲組)

s(single,單行)和 x (free-spacing, 無間隔)匹配模式

條件匹配

正則表達式注釋

Function類型

每個函數(shù)都是Function類型的實例,而且都與其他引用類型一樣具有屬性和方法

由于函數(shù)是對象,因此函數(shù)名實際上也是只想函數(shù)對象的指針,不會與某個函數(shù)綁定

function sum (num1, num2) {
    return num1 + num2;
}

// 下面使用函數(shù)表達式定義函數(shù)的方式幾乎相差無幾
// function后面沒必要使用函數(shù)名,通過變量sum即可飲用函數(shù)
// 函數(shù)末尾有一個分號,就像聲明其他變量一樣
var sum = function(num1, num2) {
    return num1 + num2;
};

不推薦 最后一種固定翼函數(shù)的方式是使用Function構(gòu)造函數(shù),可以接收任意數(shù)量的參數(shù),但最后一個參數(shù)始終但被看成是函數(shù)體,而前面的參數(shù)則枚舉出了新函數(shù)的參數(shù)。這樣會導(dǎo)致解析兩次代碼,第一次是解析常規(guī)ECMAScript代碼,第二次是解析傳入構(gòu)造函數(shù)中的字符串,從而影響性能。

// 不推薦
var sum = new Function("num1", "num2", "return num1 + num2");

函數(shù)名是指向函數(shù)的指針,因此函數(shù)名與包含對象指針的其他變量沒有區(qū)別。一個函數(shù)可能會有多個名字

function sum (num1, num2) {
    return num1 + num2;
}

var anotherSum = sum;                    // 函數(shù)指針的副本賦給了anotherSum

sum = null;                              // 清除了sum變量 anotherSum依然有效
console.log(anotherSum(10, 10));         // 20
沒有重載(深入理解)
function addSomeNumber(num) {
    return num + 100;
}
function addSomeNumber(num) {
    return numm + 200;
}
var result = addSomeNumber(100);    // 300

// 這個例子中聲明了兩個同名函數(shù),而結(jié)果是后面的函數(shù)覆蓋了前面的函數(shù)
// 以下代碼等同于上面的代碼

var addSomeNumber = function (num ) {
    return num + 100;
};
addSomeNumber = function (num ) {
    return num + 200;
};
var result = addSomeNumber(100);    // 300

在創(chuàng)建第二個函數(shù)時,實際上覆蓋了引用第一個函數(shù)的變量addSomeNumber

函數(shù)聲明與函數(shù)表達式

解析器會先解讀函數(shù)聲明,并使其在執(zhí)行任何代碼之前可用

函數(shù)表達式,則必須等到解析器執(zhí)行到它所在的代碼行,才會真正被解釋執(zhí)行

也可以同時使用函數(shù)聲明和函數(shù)表達式,(var sum = function sum () {};)不過在Safari中會導(dǎo)致錯誤

// 不會報錯
alert(sum(10, 10));
function sum(num1, mun2) {
    return num1 + num2;
}
// 報錯
alert(sum(10, 10));
var sum = function (num1, mun2) {
    return num1 + num2;
};
作為值的函數(shù)

函數(shù)名本身就是變量,所以函數(shù)也可以作為值來使用。也就是說,不僅可以像傳遞參數(shù)一樣把一個函數(shù)傳遞給另一個函數(shù),而且可以將一個函數(shù)作為另一個函數(shù)的結(jié)果返回

function callSomeFunction(someFunction, someArgument) {
    return someFunction(someArgument);
}

function add10(num) {
    return num + 10;
}

// 傳入函數(shù)指針,就不能加(),所以這里是add10
var result1 = callSomeFunction(add10, 10);

可以從一個函數(shù)中返回另一個函數(shù)

function createComparisonFunction(propertyName) {
    return function(object1, object2) {
        var value1 = object1[propertyName];
        var value2 = object2[propertyName];
        
        if (value1 < value2) {
            return -1;
        } else if (value1 > value2) {
            return 1;
        } else {
            return 0;
        }
    }
}
函數(shù)內(nèi)部屬性

在函數(shù)內(nèi)部,有兩個特殊的對象:arguments this

arguments的主要用途保存函數(shù)參數(shù),這個對象還有一個屬性callee,該屬性是一個指針,指向擁有這個arguments對象的函數(shù)

// 經(jīng)典的階乘函數(shù)
function factorial(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * factorial(num-1);
    }
}

// 如上面代碼,在函數(shù)有名字,而且名字以后也不會變的情況下,這樣定義沒有問題
// 但這個函數(shù)的執(zhí)行與函數(shù)名factorial緊緊耦合在了一起
// 下面的寫法可以避免這種問題
function factorial(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * arguments.callee(num-1);
    }
}

var trueFactorial = factorial;

fatorial = function () {
    return 0;
};

console.log(trueFactorial(5));        // 120
console.log(fatorial(5));             // 0

this 引用的是函數(shù)執(zhí)行的環(huán)境對象——或者說是this 值(當在網(wǎng)頁全局作用域中調(diào)用函數(shù)時,this對象引用的是window)

window.color = "red"
var o = { color: "blue" };

function sayColor() {
    console.log(this.color);
}

sayColor();        // "red"

o.sayColor = sayColor;
o.sayColor();        // "blue"

ECMAScript 5 規(guī)范化了另一個函數(shù)對象的屬性:caller 。Opera早起版本不支持,其他瀏覽器都支持這個ECMAScript 3并沒有定義的屬性。caller保存著調(diào)用當前函數(shù)的函數(shù)引用,在全局作用用戶中調(diào)用當前函數(shù),它的值為null

function outer() {
    inner();
}

function inner() {
    console.log(inner.caller);
}

// 打印出outer()函數(shù)的源碼
// 因為outer調(diào)用了inner,所以inner.caller就指向outer()。
outer();
// 為了實現(xiàn)更松散的耦合,也可以通過arguments.callee.caller來訪問
function outer() {
    inner();
}
function inner() {
    console.log(arguments.callee.caller);
}
outer();

當函數(shù)再嚴格模式下運行時,訪問arguments.callee會導(dǎo)致錯誤。ECMAScript 5 還定義了arguments.caller屬性,嚴格模式下也會導(dǎo)致錯誤,而在非嚴格模式下這個屬性始終是undefined。定義這個屬性是為了分清arguments.caller和函數(shù)的caller屬性。以上變化都是為了加強這門語言的安全性,這樣第三方代碼就不能再相同的環(huán)境里窺視其他代碼了。

嚴格模式還有一個限制:不能為函數(shù)caller屬性賦值,否則會導(dǎo)致錯誤。

函數(shù)屬性和方法

每個函數(shù)都包含兩個屬性:length 和 prototype

length表示函數(shù)希望接收的命名參數(shù)的個數(shù)

prototype 對于引用各類型而言,prototype是保存它們所有實例方法的真正所在。換言之,注入toString() valueOf()等方法實際上都保存在prototype名下,只不過是通過各自對象的實例訪問罷了。在創(chuàng)建自定義引用類型以及實現(xiàn)繼承時,prototype屬性的作用是極為重要的。

在ECMAScript 5 中,prototype屬性是不可枚舉的,因此使用for-in無法發(fā)現(xiàn)。

每個函數(shù)都包含兩個非繼承而來的方法:apply() call()。這兩個方法的用途都是在特定的作用域中調(diào)用函數(shù),實際上等于設(shè)置函數(shù)體內(nèi)this對象的值。

apply()方法接收兩個參數(shù):一個是在其中運行函數(shù)的作用域,另一個是參數(shù)數(shù)組。其中,第二個參數(shù)可以是Array的實例,也可以是arguments對象

在嚴格模式下,未指定對象而調(diào)用函數(shù),則this值不會轉(zhuǎn)型為window。除非明確把函數(shù)添加到某個對象或者調(diào)用apply() 或 call(),否則this值將是undefined。

call()方法與apply()的作用相同,它們的區(qū)別僅在于接收參數(shù)的方式不同。對于call()而言,第一個參數(shù)是this值沒有變化,不同的是其余參數(shù)都直接傳遞給函數(shù)。換言之,在使用call()方法時,傳遞給函數(shù)的參數(shù)必須逐個列舉出來

// callSum1()在執(zhí)行sum()函數(shù)時傳入了this作為this值,所以傳入的就是window對象
function sum(num1, num2) {
    return num1 + num2;
}
function callSum1(num1, num2) {
    return sum.apply(this, arguments);                //    傳入arguments對象
}

function callSum2(num1, num2) {
    return sum.apply(this, [num1, num2]);            //     傳入數(shù)組
}

function callSum3(num1, num2) {
    return sum.call(this, num1, num2);            //     傳入數(shù)組
}

// 在全局環(huán)境下調(diào)用函數(shù),此時this就是window
callSum1(10, 10));                                    // 20
callSum2(10, 10));                                    // 20
callSum3(10, 10));                                    // 20

apply() call() 真正強大的地方是能夠擴充函數(shù)賴以運行的作用域

window.color = "red";
var o = { color: "blue" };

function sayColor() {
    console.log(this.color);
}

sayColor();        // red
sayColor.call(this);        // red
sayColor.call(window);      // red
sayColor.call(o);           // blue

使用call() apply() 來擴充作用域的最大好處,就是對象不需要與方法有任何耦合關(guān)系

ECMAScript 5 還定義了一個方法: bind() 這個方法會創(chuàng)建一個函數(shù)的實例,其this值會被綁定到傳給bind()函數(shù)的值.支持bind()方法的瀏覽器IE9+, Firefox 4+,Safari 5.1+, Opera 12+ Chrome

window.color = "red";
var o = { color: "blue" };
function sayColor() {
    console.log(this.color);
}

var objectSayColor = sayColor.bind(o);
objectSayColor();        // blue

每個函數(shù)繼承的toLocaleString() 和 toString() valueOf() 方法都之中返回函數(shù)的代碼。

基本包裝類型

為了便于操作基本類型值,ECMAScript還提供了3個特殊的引用類型: Boolean, Number, String

每當讀取一個基本類型值得時候,后臺就會創(chuàng)建一個對應(yīng)的基本包裝類型的對象,從而讓我們能夠調(diào)用一些方法來操作這些數(shù)據(jù)。

// 后臺自動完成下列處理
// 創(chuàng)建String類型的一個實例
// 在實例上調(diào)用指定的方法
// 銷毀這個實例
var s1 = "some text";
var s2 = s1.substring(2);

// 可以想象執(zhí)行了以下代碼
var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;
// 經(jīng)過此番處理,基本的字符串值就變得跟對象一樣了。

以上步驟也分別適用于Boolean Number類型對應(yīng)的布爾值和數(shù)字值

引用類型與基本包裝類型的主要區(qū)別就是對象的生存期。使用new操作符創(chuàng)建的引用類型的實例,在執(zhí)行流離開當前作用域之前都一直保存在內(nèi)存中。而自動創(chuàng)建的基本包裝類型的對象,則只存在于一行代碼的執(zhí)行瞬間,然后立即銷毀。這意味著我們不能再運行時為基本類型值添加屬性和方法

var s1 = "some text";
// 這里創(chuàng)建的String對象在執(zhí)行第三行代碼時就已經(jīng)被銷毀了
s1.color = "red";
// 這里又創(chuàng)建了自己的String對象,而該對象沒有color屬性
console.log(s1.color);          // undefined

可以顯式的調(diào)用Boolean,Number,String來創(chuàng)建基本包裝類型的對象。但應(yīng)該在必要的時候這樣做,因為很容易分不清實在處理基本類型還是引用類型的值。

對基本包裝類型的實例調(diào)用typeof會返回"object",而且所有基本包裝類型的對象都會被轉(zhuǎn)為布爾值true

Object構(gòu)造函數(shù)也會像工廠方法一樣,根據(jù)傳入值的類型返回相應(yīng)基本包裝類型的實例。

var obj = new Object("some text");
console.log(obj instanceof String);         // true

使用new調(diào)用基本包裝類型的構(gòu)造函數(shù),與直接調(diào)用同名的轉(zhuǎn)型函數(shù)是不一樣的

// number中保存的是基本類型的值25
// obj中保存的是Number的實例(對象)
var value = "25";
var number = Number(value);     // 轉(zhuǎn)型函數(shù)
console.log(typeof number);     // "number"

var obj = new Number(value);    // 構(gòu)造函數(shù)
console.log(typeof obj);        // "object"
Boolean類型

Boolean類型的實例重寫了valueOf()方法,返回基本類型值true或false

重寫了toString()方法,返回字符串"true" "false"

可是Boolean對象在ECMAScript中的用處不大,因為經(jīng)常造成誤解。其中最常見的問題就是在布爾表達式中使用Boolean對象

基本類型與引用類型的布爾值還有兩個區(qū)別。

typeof操作符對基本類型返回"boolean", 引用類型返回"object"

由于Boolean對象是Boolean類型的實例,所以使用instanceof操作符測試Boolean對象會返回true,而測試基本類型的布爾值則返回false

// 使用Boolean對象生成的實例,在布爾表達式中,等同于一個普通對象
// 所以result1 返回true
var falseObject = new Boolean(false);
var result1 = falseObject && true;                   // true

var falseValue = false;
var result2 = falseValue && true;                   // false

console.log(typeof falseOjbect);                    // object
console.log(typeof falseValue);                     // boolean
console.log(falseObject instanceof Boolean);        // true
console.log(falseValue instanceof Boolean);         // false

理解基本類型的布爾值與Boolean對象之間的區(qū)別非常重要——當然,我們建議是永遠不要使用Boolean對象

Number類型

toLocaleString() toString() 返回字符串形式的數(shù)值

valueOf() 返回基本類型的數(shù)值

toString() 傳遞一個表示基數(shù)的參數(shù),告訴它返回幾進制的字符串形式

var num = 10;
console.log(num.toString());                      // "10"
console.log(num.toString(2));                     // "1010"
console.log(num.toString(8));                     // "12"
console.log(num.toString(10));                    // "10"
console.log(num.toString(16));                    // "a"

除了繼承的方法,NUmber類型還提供了一些用于將數(shù)值格式化為字符串的方法。

toFixed() 按照指定的小數(shù)位返回數(shù)值的字符串表示。

超出位數(shù)的會進行攝入,舍入規(guī)則因瀏覽器而異,IE8及之前不能正確舍入的范圍在{(-0.94,-0.5],[0.5,0.94)])},在這個范圍內(nèi),IE會返回0,而不是-1或1,IE9修復(fù)了這個問題。

標準實現(xiàn)的規(guī)范,toFixed() 尅表示帶有0到20個小數(shù)位的數(shù)值,有些瀏覽器可以實現(xiàn)更多

toExponential() 返回以指數(shù)表示法(也稱e表示法)表示的數(shù)值的字符串形式。同樣接受一個參數(shù),制定輸出結(jié)果的小數(shù)位

var num = 10;
console.log(num.toExponentail(1));                // "1.0e+1"

toPrecision() 這個方法會返回一個合適的表達方式 返回固定大?。╢ixed)格式,也可能返回指數(shù)(exponential)格式

var num = 99;
console.log(num.toPrecision(1));                 // "1e+2"
console.log(num.toPrecision(2));                 // "99"
console.log(num.toPrecision(3));                 // "99.0"

同樣,我們不建議直接實例化Number類型,原因與創(chuàng)建Boolean對象一樣

var numberObject = new Number(10);
var numberValue = 10;
console.log(typeof numberObject);        // "object"
console.log(typeof numberValue);         // "number"
console.log(numberObject instanceof Number);         // true
console.log(numberValue instanceof Number);          // false
String類型

繼承的方法 valueOf() toLocaleString() toString() 都返回字符串所表示你的基本字符串值

String類型每個實例都有一個length屬性,表示字符串中包含多少個字符。即使字符串中包含雙字節(jié)字符串(不是占一個字節(jié)的ASCII字符),每個字符也仍然算一個字符。

var stringValue = "hello world";
console.log(stringValue.length);         // "11"
字符方法

兩個用于訪問字符串中特定字符的方法是 charAt() charCodeAt() 都接受一個參數(shù),基于0的字符位置。

charAt() 方法以單字符字符串的形式返回給定位置的那個字符(ECMAScript中沒有字符類型)

var stringValue = "hello world";
console.log(stringValue.charAt(1));     // "e"

charCodeAt() 返回字符編碼

var stringValue = "hello world";
console.log(stringValue.charCodeAt(1));     // "101" 小寫e的字符編碼

ECMAscript還定義了方括號訪問字符的方法 IE7及以前的版本會返回undefined值

var stringValue = "hello world";
console.log(stringValue[1]);     // "e" 
字符串的操作方法

concat() 用于將一個或多個字符串拼接起來,返回拼接得到的新字符串,可以接受任意多個參數(shù)。雖然concat()實現(xiàn)了拼接方法,但實踐中更多還是使用加號操作符(+),簡單易行。

var stringValue = "hello ";
var result1 = stringValue.concat("world");     // "hello world"
var result2 = stringValue.concat("world", "!");     // "hello world!"
console.log(stringValue);                     // "hello

ECMAscript還提供了三個基于子字符串創(chuàng)建新字符串的方法 slice() substr() substring()

這個三個方法都會返回被操作符字符串的一個子字符串,而且也都接收一個或兩個參數(shù)。第一個參數(shù)制定字符串的開始位置,第二個(可選)表示子字符串到哪里結(jié)束

三個方法都不會修改字符串本身的值——它們只是返回一個基本類型的字符串值,對于原始字符串沒有任何影響

slice() substring() 的第二個參數(shù)制定的是字符串最后一個字符后的位置

substr() 的第二個參數(shù)制定的則是返回的字符個數(shù)

var stringValue = "hello world";
console.log(stringValue.slice(3));       // "lo world"
console.log(stringValue.substring(3));   // "lo world"
console.log(stringValue.substr(3));      // "lo world"

// substr() 方法第二個參數(shù)制定是要返回的字符個數(shù)
// 而slice()  substring() 指定的是結(jié)束位置 
// "world"中的o處于位置7,因此結(jié)果中不包含o
console.log(stringValue.slice(3, 7));       // "lo w"
console.log(stringValue.substring(3, 7));   // "lo w"
console.log(stringValue.substr(3, 7));      // "lo worl"

在參數(shù)是負值的情況下,它們的行為就不盡相同了

var stringValue = "hello world";

// slice() 會將傳入的負值與字符串的長度相加
// substring() 會將傳入的負值轉(zhuǎn)換為0
// substr() 第一個參數(shù)如果是負值會加上字符串長度,第二個參數(shù)如果是負值,就會轉(zhuǎn)換為0
console.log(stringValue.slice(-3));       // "rld"
console.log(stringValue.substring(-3));   // "hello world"
console.log(stringValue.substr(-3));      // "rld" 

console.log(stringValue.slice(3, -4));       // "lo w"
// 這里實際上相當于substring(3, 0),而這個方法會將較小的參數(shù)作為開始位置
console.log(stringValue.substring(3, -4));   // "hel"
console.log(stringValue.substr(3, -4));      // ""

字符串的位置方法

indexOf() lastIndexOf() 從一個字符串搜索給定的字符串,然后返回字符串的位置(沒有找到就返回-1)。lastIndexOf() 從末尾向前搜索

兩個方法都可以接受第二個參數(shù),表示從字符串中的哪個位置開始搜索。indexOf() 會忽略置頂位置之前的向后搜索,而lastIndexOf() 則相反

var stringValue = "hello world";
console.log(stringValue.indexOf("o"));       // 4
console.log(stringValue.lastIndexOf("o"));   // 7

console.log(stringValue.indexOf("o", 6));       // 7
console.log(stringValue.lastIndexOf("o", 6));   // 4

在使用第二個參數(shù)的情況下,可以通過循環(huán)調(diào)用indexOf()或lastIndexOf()來找到所有匹配的子字符串

var stringValue = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
var positions = new Array();
var pos = stringValue.indexOf("e");

while(pos > -1) {
  positions.push(pos);
  pos = stringValue.indexOf("e", pos + 1);
}

console.log(posisionts);                 // [3, 24, 32, 35, 52]
trim() 方法

ECMAScript為所有字符串定義了trim()方法。創(chuàng)建一個字符串的副本,刪除前置及后綴的所有空格,然后返回結(jié)果

IE9+, Firefox3.5+, Safari5+, Opera10.5+, Chrome 8+ 還支持trimLeft() trimRight()

var str = "    hello world     "     
str.trim();                           // "hello world"
console.log(str);                     // "    hello world     "     
字符串大小寫轉(zhuǎn)換方法

toLowerCase(), toUpperCase() 是兩個經(jīng)典方法,借鑒自java.lang.String的同名方法

toLocaleLowerCase(), toLocaleUpperCase() 方法則是針對特定地區(qū)的實現(xiàn)。部分地區(qū)(包括簡體中文),和上面兩個方法得到的值相同,但少數(shù)語言(如土耳其語)會為Unicode大小寫轉(zhuǎn)換應(yīng)用特殊的規(guī)則,這時就必須使用針對地區(qū)的方法來保證實現(xiàn)的正確的轉(zhuǎn)換

var stringValue = "hello world";
console.log(stringValue.toLocaleUpperCase());                 // "HELLO WORLD"
console.log(stringValue.toUpperCase());                       // "HELLO WORLD"
console.log(stringValue.toLocaleLowerCase());                 // "hello world"
console.log(stringValue.toLowerCase());                       // "hello world"
字符串的模式匹配方法

match() 在字符串上調(diào)用這個方法,本質(zhì)上與調(diào)用RegExp的exec()方法相同。只接收一個參數(shù),要么是一個正則表達式,要么是一個RegExp對象

var txt = "cat, bat, sat, fat";
var pattern = /.at/;

// 與pattern.exec()相同
var matches = txt.match(pattern);
console.log(matches.index);                  // 0
console.log(matches[0]);                     // "cat"
console.log(matches.lastIndex);              // 0

另一個用于查找模式的方法是search() 唯一的參數(shù)與match()相同,返回字符串中第一個匹配項的索引;如果沒有返回-1

var txt = "cat, bat, sat, fat";
var pos = txt.search(/at/);
console.log(pos);                  // 1

為了簡化替換子字符串的操作,ECMAscript提供了replace()方法,兩個參數(shù),一個是RegExp對象或者一個字符串(這個字符串不會被轉(zhuǎn)成正則表達式),第二個參數(shù)可以是一個字符串或者一個函數(shù)。如果第一個參數(shù)是字符串,那么只會替換掉第一個子字符串。要想替換所有子字符串,唯一的辦法就是提供一個正則表達式,而起要制定全局標識(g)

var txt = "cat, bat, sat,  fat";
var result = txt.replace("at", "ond");             // "cound, bat, sat, fat"
result = txt.replace(/at/g, "ond");                // "cond, bond, sond, fond"

第二個參數(shù)是字符串,還可以使用一些特殊子反復(fù)序列,將正則表達式操作得到的值插入到結(jié)果字符串中。

| 字符序列 | 替換文本 |
| -------- | ----------------------------------------------------------------------------------------------------------- |
| $$ | $ |
| $& | 匹配整個模式的子字符串。與RegExp.lastMatch的值相同 |
| $" | 匹配子字符串之前的字符串。與RegExp.leftContext的值相同 |
| $` | 匹配子字符串之后的字符串。與RegExp.rightContext的值相同 |
| $n | 匹配第n個捕獲組的子字符串,其中n等于0~9。$0,$1...$9 。如果正則表達式中沒有定義捕獲組,則使用空字符串 |
| $nn | 匹配第nn個捕獲組的子字符串,其中n等于01~99。$01,$02...$99 。如果正則表達式中沒有定義捕獲組,則使用空字符串 |

var txt = "cat, bat, sat, fat";
result = txt.replace(/(.at)/g, "word ($1)");         
// word (cat), word (bat), word (sat), word (fat)

第二個參數(shù)是函數(shù)。在只有一個匹配項(即與模式匹配的字符串)的情況下,會向這個函數(shù)傳遞三個參數(shù):模式的匹配項(定義了多個捕獲組,這里就會有多個)、模式匹配項在字符串中的位置和原始字符串。

function htmlEscape(text) {
  return text.replace(/[<>"&]/g, function(match, pos, orginalText) {
    switch (match) {
      case "<":
        return "<";
      case ">":
        return ">";
      case "&":
        return "&";
      case """:
        return """;
    }
  });
}
console.log(htmlEscape("

Hello world!

")) //

Hello world!

split() 方法可以基于指定的分隔符將一個字符串分割成多個子字符串,并將結(jié)果放在一個數(shù)組中。分隔符可以是字符串,也可以是一個RegExp對象(這個方法不會將字符串看成正則表達式)。split() 方法可以接受可選的第二個參數(shù),用于指定數(shù)組的大小,以便確保返回的數(shù)組不會超過既定大小。

var colorText = "red,blue,green,yellow";
var colors1 = colorText.split(",");                  // ["red", "blue", "green", "yellow"]
var colors2 = colorText.split(",", 2);               // ["red", "blue"]

// 需要注意的是,返回結(jié)果第一項和最后一項是空字符串
// /[^,]+/ 表示匹配逗號之前的單詞 不包括逗號 匹配項就是
// "red" "blue" “green" "yellow"
// "red"之前和“yellow"之后沒有字符,所以第一項和最后一項是空字符串
var colors3 = colorText.split(/[^,]+/);             // ["", ",", ",", ",", ""]
localeCompare() 方法

這個方法比較兩個字符串,并返回下列值中的一個:

如果字符串在字母表中應(yīng)該排在字符串參數(shù)之前,則返回一個負數(shù),(大多數(shù)情況下是-1,具體的值要視實現(xiàn)而定)

如果字符串等于字符串參數(shù),則返回0

如果字符串在字母表中應(yīng)該排在字符串參數(shù)之后,則返回一個正數(shù)(大多數(shù)情況下是1, 具體的值同樣要視實現(xiàn)而定)。

var stringValue = "yellow";
console.log(stringValue.localeCompare("brick"));                        // 1
console.log(stringValue.localeCompare("yellow"));                       // 0
console.log(stringValue.localeCompare("zoo"));                          // -1

再次強調(diào),因為localeCompared() 返回的數(shù)值取決于實現(xiàn),所以最好是像下面所示

function determineOrder(value) {
  var result = stringValue.localeCompare(value);
  if (result < 0) {
    console.log("The string "yellow" comes before the string "" + value + "".");
  } else if (result > 0) {
    console.log("The string "yellow" comes after the string "" + value + "".");
  } else {
    console.log("The string "yellow" is equal to the string "" + value + "".");
  }
}

determineOrder("brick");
determineOrder("yellow");
determineOrder("zoo");
fromCharCode() 方法

這個方法的任務(wù)是接收一或多個字符編碼,然后將它們轉(zhuǎn)換成一個字符串

console.log(String.fromCharCode(104, 101, 108, 108, 111));    // "hello"
HTML 方法

早期的web瀏覽器實現(xiàn)了一些專門用于簡化HTML格式化任務(wù)的方法,不建議使用

單體內(nèi)置對象

ECMA-262對內(nèi)置對象的定義:“由ECMAScript實現(xiàn)提供的、不依賴于宿主環(huán)境的對象,這些對象在ECMAScript程序執(zhí)行之前就已經(jīng)存在了?!币馑际情_發(fā)者不必顯式的實例化內(nèi)置對象,因為它們已經(jīng)實例化了。

Global 對象

ECMAScript中的Global對象在某種意義上是作為一個終極的“兜底兒對象”。不屬于任何其他對象的屬性和方法,最終都是它的屬性和方法。

所有在全局作用域中定義的屬性和函數(shù)都是Global對象的屬性。

諸如 isNaN(), isFinite(), parseInt(), parseFloat() 實際上全都是Global對象的方法。除此之外,Global還包含其他一些方法。

URI編碼方法

Gloabal對象的encodeURI() 和 encodeURIComponent() 方法可以對URI(Uniform Resource Identifiers, 通用資源標識符)進行編碼,以便發(fā)送給瀏覽器。有效的URI中不能包含某些字符,例如空格。而這兩個URI編碼方法就可以對URI進行編碼,它們特殊的UTF-8編碼替換所有無效的字符,從而讓瀏覽器能夠接受和理解。

encodeURI() 主要用于整個URI(例如 http://www.wrox.com/illegal value.htm) 不會對本身屬性URI的特殊字符進行編碼,例如冒號、正斜杠、問好和井字號

encodeURIComponent() 主要用于對URI中的某一段(例如前面URI中的illegal value.htm)進行編碼。會對發(fā)現(xiàn)的任何非標準字符進行編碼。

var uri = "http://www.wrox.com/illegal value.htm#start";
encodeURI(rui);                  // "http://www.wrox.com/illegal%20value.htm#start"
encodeURIComponent(rui);        // "http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start"

// encodeURI 只對空格編碼
// encodeURIComponents 所有非字母數(shù)字字符

與encodeURI() 和 encodeURIComponent() 方法對應(yīng)的是 decodeURI() decodeURIComponent()

dencodeURI() 只能對encodeURI()替換的字符進行編碼。%20替換成一個空格,但不會對%23(#)作處理

decodeURIComponent() 能解碼所有字符

eval() 方法

最后一個,大概也是ECMAScript中最強大的方法。它只接受一個參數(shù),即,要執(zhí)行的的ECMAScript(或 JavaScript)字符串

eval() 中創(chuàng)建的任何變量或函數(shù)都不會被提升,因為在解析代碼的時候,它們被包含在一個字符串中,只在eval() 執(zhí)行的時候創(chuàng)建

eval("var msg = "hello world";");
console.log(msg);                       // hello world

eval("function sayHi() { alert("hi"); }");
sayHi();

嚴格模式下,在外部訪問不到eval()中創(chuàng)建的任何變量或函數(shù),因此前面兩個例子都會導(dǎo)致錯誤。

在嚴格模式下,為eval賦值也會導(dǎo)致錯誤

"use strict"
eval = "hi";           // causes error

使用eval()時必須極為謹慎,特別實在用它執(zhí)行用戶輸入數(shù)據(jù)的情況下。否則可能會有惡意用戶輸入威脅你的站點或應(yīng)用程序安全的代碼(即所謂的代碼注入

Global對象的屬性

有些屬性之前介紹過,諸如 undefined, NaN, Infinity 都是Global對象的屬性。此外所有原生引用類型的構(gòu)造函數(shù),像Object Function也都是Global對象的屬性

屬性 說明
undefined 特殊值undefined
NaN 特殊值NaN
Infinity 特殊值Infinity
object 構(gòu)造函數(shù)object
Array 構(gòu)造函數(shù)Array
Function 構(gòu)造函數(shù)Function
Boolean 構(gòu)造函數(shù)Boolean
String 構(gòu)造函數(shù)String
Number 構(gòu)造函數(shù)Number
Date 構(gòu)造函數(shù)Date
RegExp 構(gòu)造函數(shù)RegExp
Error 構(gòu)造函數(shù)Error
EvalError 構(gòu)造函數(shù)RegExp
RangeError 構(gòu)造函數(shù)RangeError
ReferenceError 構(gòu)造函數(shù)ReferenceError
SyntaxError 構(gòu)造函數(shù)SyntaxError
TypeError 構(gòu)造函數(shù)TypeError
URIError 構(gòu)造函數(shù)URIError

ECMAScript 5 明確進制給undefined, NaN 和 Infinity 賦值, 這樣做即使在非嚴格模式下也會導(dǎo)致錯誤。

window對象

ECMAScript 雖然沒有指出如何直接訪問global對象,但Web瀏覽器都是將這個全局對象作為window對象的一部分加以實現(xiàn)。因此全局作用域中聲明的所有變量和函數(shù),就都成為了window對象的屬性

另一種取得Global對象的方法是使用this

var global = function() {
  return this;
}();
Math 對象

與JavaScript直接編寫的計算功能相比,Math對象提供的計算功能執(zhí)行起來要快的多。

Math對象的屬性

屬性 說明
Math.E 自然對數(shù)的底數(shù),即常量e的值
Math.LN10 10的自然對數(shù)
Math.LN2 2的自然對數(shù)
Math.LOG2E 以2為底e的對數(shù)
Math.LOG10E 以10為底e的對數(shù)
Math.PI π的值
Math.SQRT1_2 1/2的平方根
Math.SQRT2 2的平方根

min() max() 方法用于確定一組數(shù)值中的最小值和最大值??梢越邮杖我鈧€數(shù)值參數(shù)。

var max = Math.max(3, 54, 32, 16);  // 54
var min = Math.min(3, 54, 32, 16);  // 3

找到數(shù)組中的最大或最小值,可以像下面這樣使用

這個技巧的關(guān)鍵是把Math作為apply()的第一個參數(shù),從而正確的設(shè)置this值,然后可以將任何數(shù)組作為第二個參數(shù)(作為arguments對象)

var values = [1, 2, 3, 5, 6, 7, 8];
// 這個寫法相當于 把數(shù)組的項作為一個個數(shù)值參數(shù)傳給函數(shù)
// Math.max(1, 2, 3, 5, 6, 7, 8)
var max = Math.max.apply(Math, values);
var min = Math.min.apply(Math, values);

舍入方法 將小數(shù)值舍入為整數(shù)的幾個方法:Math.ceil(), Math.floor(), Math.round()

Math.ceil() 執(zhí)行向上舍入,即它總是將數(shù)值向上舍入為最接近的整數(shù)

Math.floor() 執(zhí)行向下舍入,即它總是將數(shù)值向下舍入為最接近的整數(shù)

Math.round() 執(zhí)行標準舍入,即它總是將數(shù)值四舍五入為最接近的整數(shù)

random() 返回大于等于0小于1的一個隨機數(shù)

// 隨機生成一個1到10之間的數(shù)值
var num = Math.floor(Math.random() * 10 + 1);

function selectFrom(lowerValue, upperValue) {
  var choices = upperValue - lowerValue + 1;
  return Math.floor(Math.random() * choices + lowerValue);
}
var num = selectFrom(2, 10);                   // 介于2和10之間(包括2和10)的一個數(shù)值

// 利用這個函數(shù)可以方便的從數(shù)組中隨機取出一項
var colors = ["red", "green", "blue", "yellow", "black", "purple", "brown"]
var color = colors[selectFrom(0, colors.length - 1)];
其他方法
方法 說明
Math.abs(num) 返回num的絕對值
Math.exp(num) 返回Math.E的num次冪
Math.log(num) 返回num的自然對數(shù)
Math.pow(num, power) 返回num的power次冪
Math.sqrt(num) 返回num的平方根
Math.acos(x) 返回x的反余弦值
Math.asin(x) 返回x的反正弦值
Math.atan(x) 返回x的反正切值
Math.atan2(y,x) 返回y/x的反正切值
Math.cos(x) 返回x的余弦值
Math.sin(x) 返回x的正弦值
Math.tan(x) 返回x的正切值

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/109379.html

相關(guān)文章

  • JavaScript高級程序設(shè)計》(3讀書筆記 4 變量、作用域和內(nèi)存問題

    摘要:具體說就是執(zhí)行流進入下列任何一個語句時,作用域鏈就會得到加長語句的塊。如果局部環(huán)境中存在著同名的標識符,就不會使用位于父環(huán)境中的標識符訪問局部變量要比訪問全局變量更快,因為不用向上搜索作用域鏈。 基本類型和引用類型的值 ECMAscript變量包含 基本類型值和引用類型值 基本類型值值的是基本數(shù)據(jù)類型:Undefined, Null, Boolean, Number, String ...

    lidashuang 評論0 收藏0
  • JavaScript高級程序設(shè)計》(3讀書筆記 1~2

    摘要:表示應(yīng)該立即下載腳本,但不應(yīng)妨礙頁面中的其他操作可選。表示通過屬性指定的代碼的字符集。表示腳本可以延遲到文檔完全被解析和顯示之后再執(zhí)行。實際上,服務(wù)器在傳送文件時使用的類型通常是,但在中設(shè)置這個值卻可能導(dǎo)致腳本被忽略。 第1章 JavaScript 簡介 雖然JavaScript和ECMAScript通常被人們用來表達相同的含義,但JavaScript的含義比ECMA-262要多得多...

    Corwien 評論0 收藏0
  • JavaScript高級程序設(shè)計》(3讀書筆記 7 函數(shù)表達式

    摘要:定義函數(shù)表達式的方式有兩種函數(shù)聲明。不過,這并不是匿名函數(shù)唯一的用途。可以使用命名函數(shù)表達式來達成相同的結(jié)果閉包匿名函數(shù)和閉包是兩個概念,容易混淆。匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其對象通常指向通過改變函數(shù)的執(zhí)行環(huán)境的情況除外。 定義函數(shù)表達式的方式有兩種: 函數(shù)聲明。它的重要特征就是 函數(shù)聲明提升(function declaration hoisting) 即在執(zhí)行代碼之前會...

    鄒立鵬 評論0 收藏0
  • JavaScript高級程序設(shè)計》(3讀書筆記 11 DOM拓展

    摘要:對的兩個主要拓展是選擇和。以下插入標記的拓展已經(jīng)納入了規(guī)范。在寫模式下,會根據(jù)指定的字符串創(chuàng)建新的子樹,然后用這個子樹完全替換調(diào)用元素。在刪除帶有時間處理程序或引用了其他對象子樹時,就有可能導(dǎo)致內(nèi)存占用問題。 盡管DOM作為API已經(jīng)非常完善了,但為了實現(xiàn)更多功能,仍然會有一些標準或?qū)S械耐卣埂?008年之前,瀏覽器中幾乎所有的拓展都是專有的,此后W3C著手將一些已經(jīng)成為事實標準的專...

    luck 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<