權(quán)威指南讀書筆記 第一部分

關(guān)于省略分號的換行

javascript在解析時,會把省略分號的行與下一行一起解析,當(dāng)不構(gòu)成語法錯誤時回合為一行,因此類庫的保守寫法,會在已開始前添加分號,以防出現(xiàn)上述問題。

關(guān)于分?jǐn)?shù)的精度問題

javascript可以精確地表示分?jǐn)?shù)1/2、1/8等,通常所用的1/10、1/100不能被精確地表示出來。

    var x=.3-.2;
    var y=.2-.1;
    x==y //false
    x==.1 //false
    y==.1 //true

解決方案,當(dāng)進(jìn)行相關(guān)計算可以換算成整數(shù)計算,最后使用科學(xué)計數(shù)法或單位換算進(jìn)行結(jié)果的應(yīng)用。

關(guān)于進(jìn)制的問題

嚴(yán)格模式下禁止8禁止模式。ECMAscript不支持八進(jìn)制的直接量。

多行字符串

JS中多遇到拼接字符串的問題,通常情況下會拼接一個超長字符串在一行,使文檔可讀性下降,可以使用換行符,使得一個字符串可以在多行寫出。
在ECMAscript 3 中,字符串必須寫在一行,但是在ESMAscript5 中字符串可以被拆成多行,每行一反斜線()結(jié)束,反斜線和行結(jié)束符都不算是字符串直接量的內(nèi)容。如果希望再字符串直接量中另起一行,可以使用轉(zhuǎn)義字符\n

    "on
    \line" 
    //輸出為online

關(guān)于轉(zhuǎn)義字符

反斜杠使我們避免使用常規(guī)方式解釋單引號,當(dāng)單引號不是用來標(biāo)記字符串結(jié)尾時,他只是一個‘。
ESMAScript5,允許在一個多行字符串直接量里的每行結(jié)束處使用反斜杠。

You\'re right, it can\'t be a quote.

關(guān)于模式匹配

盡管RegExp并不是語言中的基本數(shù)據(jù)類型,但是他們依然具有直接量寫法,可以直接在javascript程序中使用。在兩條斜線之間的文本它構(gòu)成了一個正則表達(dá)式直接量。第二條斜線之后也可以跟隨一個或多個字母,用來修飾匹配模式的含義

    var text = "testing:1,2,3";
    var pattern=/\d+/g
    partten.test(text) // 匹配成功
    text.search(pattern) //9 首次匹配成功的位置
    text.match(pattern) //["1","2","3"]所有匹配組成的數(shù)組
    text.replace(pattern,"#"); //"testing:#,#,#"
    text.split(/\D+/);//["","1","2","3"]用非數(shù)字字符截取字符串

關(guān)于全局對象

全局屬性: undefined infinity NaN
全局函數(shù): isNaN() parseInt() eval()
構(gòu)造函數(shù) : Date() RegExp() String() Object() Array()
全局對象:Math JSON

關(guān)于包裝對象

對于string、bollen、num為什么會有屬性呢,只要應(yīng)用了字符串的屬性,javascript就會將字符串值通過調(diào)用new String(s)的方式注冊能換成為對象,這個對象繼承了字符串的方法。并被用來處理屬性的引用,一旦屬性引用結(jié)束,這個新創(chuàng)建的對象就會銷毀。
??當(dāng)讀取字符串、數(shù)字、和布爾值的屬性值的時候,表現(xiàn)的想對象一樣,但是如果你試圖給屬性賦值,則會忽略這個操作;修改只是發(fā)生在臨時對象上,而這個臨時對象并沒有被保留下來。

  • 存取字符串和數(shù)字布爾值的屬性時創(chuàng)建的臨時對象稱為包裝對象。
  • 字符串?dāng)?shù)字和布爾值的屬性值是只讀的,并且不能定義新屬性。

關(guān)于對象的轉(zhuǎn)換

對象到字符串

  • 調(diào)用toString()方法,把返回值進(jìn)行字符串的隱式轉(zhuǎn)換。
  • 沒有toString()方法,調(diào)用valueOf(),并隱式轉(zhuǎn)換返回值。
  • 否則拋出類型異常

對象到數(shù)字

  • 對象具有valueOf()方法,把返回值進(jìn)行數(shù)字的隱性轉(zhuǎn)換。
  • 沒有valueOf()方法,調(diào)用toString()方法,把返回值進(jìn)行數(shù)字的隱形轉(zhuǎn)換
  • 否則拋出類型異常

空數(shù)組返回0的原因:
數(shù)組繼承了默認(rèn)的valueOf()方法,這個方法返回一個對象而不是一個原始值,因此數(shù)組到數(shù)字的轉(zhuǎn)換則調(diào)用toString方法??諗?shù)組轉(zhuǎn)換成為空字符串,空字符串轉(zhuǎn)換為數(shù)字0.

關(guān)于作為屬性的變量

    var trunevar = 1; //聲明一個不可刪除的全局變量
    fakevar = 2;//創(chuàng)建全局對象的一個可刪除的屬性
    this.fakevar2 = 3;
    delete trunevar //false
    delete fakevar //true
    delete this.fakevar2 //true

關(guān)于運(yùn)算符

運(yùn)算要求操作的數(shù)是整數(shù),這些整數(shù)表示32位整型

按位非:
~ox0F = oxFFFFFFF0  表示為-16

左移和右移的位數(shù)是0~31之間的一個整數(shù)

帶符號右移:
右邊溢出將忽略,左邊按照原有操作數(shù)符號來補(bǔ)位,補(bǔ)成一致的。

無符號右移:
最高位總是由0填補(bǔ)
-1>>>4=ox0FFFFFFF

關(guān)于相等和嚴(yán)格相等

嚴(yán)格相等:

  • 明確類型不進(jìn)行類型轉(zhuǎn)換
  • null ===null //false
  • undefined ===undefined //false
  • NaN === NaN //false

相等:

  • null ==undefined //true
  • '1' == true //true

關(guān)于邏輯非

恒等式
!(p&&q) === !p||!q
!(p||q) === !p&&!q

關(guān)于eval()

    var geval = eval;
    var x ='global',y='global';
    function f(){
        var x='local';
        eval("x+='change';");//改變局部變量
        return x;
    }
    function g(){
        var y='local';
        geval("y+='change';");//改變?nèi)肿兞?        return y;
    }
    console.log(f(),x);   //"local changeglobal"
    console.log(g(),y);   //"local globalchange"

關(guān)于 typeof

數(shù)據(jù)類型 計算值
NaN number
函數(shù) function
宿主對象 由編譯器各自實(shí)現(xiàn)的字符串

本地對象、內(nèi)置對象和 宿主對象

1、本地對象

ECMA-262 把本地對象(native object)定義為“獨(dú)立于宿主環(huán)境的 ECMAScript 實(shí)現(xiàn)提供的對象”。

再來看一下,“本地對象”包含哪些內(nèi)容:

Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError

由此可以看出,簡單來說,本地對象就是 ECMA-262 定義的類(引用類型)。

2、內(nèi)置對象

ECMA-262 把內(nèi)置對象(built-in object)定義為“由 ECMAScript 實(shí)現(xiàn)提供的、獨(dú)立于宿主環(huán)境的所有對象,在 ECMAScript 程序開始執(zhí)行時出現(xiàn)”。這意味著開發(fā)者不必明確實(shí)例化內(nèi)置對象,它已被實(shí)例化了。

同樣是“獨(dú)立于宿主環(huán)境”。根據(jù)定義我們似乎很難分清“內(nèi)置對象”與“本地對象”的區(qū)別。而ECMA-262 只定義了兩個內(nèi)置對象,即 Global 和 Math (它們也是本地對象,根據(jù)定義,每個內(nèi)置對象都是本地對象)。

如此就可以理解了。內(nèi)置對象是本地對象的一種。而其包含的兩種對象中,Math對象我們經(jīng)常用到,可這個Global對象是啥東西呢?

Global 對象是ECMAScript中最特別的對象,因?yàn)閷?shí)際上它根本不存在,但大家要清楚,在ECMAScript中,不存在獨(dú)立的函數(shù),所有函數(shù)都必須是某個 對象的方法。類似于isNaN()、parseInt()和parseFloat()方法等,看起來都是函數(shù),而實(shí)際上,它們都是Global對象的方 法。而且Global對象的方法還不止這些。有關(guān)Global對象的具體方法和屬性,感興趣的同學(xué)可以看一下這里:JavaScript 全局對象參考手冊

3、 宿主對象

由ECMAScript實(shí)現(xiàn)的宿主環(huán)境提供的對象,可以理解為:瀏覽器提供的對象。所有的BOM和DOM都是宿主對象。

關(guān)于void 運(yùn)算符

出現(xiàn)在操作數(shù)之前,操作數(shù)可以是任意類型。void會忽略操作數(shù)的值,因此在操作數(shù)據(jù)有副作用的時候使用void來讓程序更具有語意。

運(yùn)算符用于客戶端的URL——javascript:URL中,在URL中可以寫帶有副作用的表達(dá)式,而void則讓瀏覽器不必顯示這個表達(dá)式的計算結(jié)果

<a href='javascript:void window.open();'>打開一個新的窗口</a>

關(guān)于switch

  • 查找case中的表達(dá)式和expression的值全等于(===)進(jìn)行匹配,表達(dá)式和case不會做模式的轉(zhuǎn)換。
  • 如果匹配不成功的話會執(zhí)行default,如果沒有default則會跳過所有的代碼塊。
  • case只表明了起點(diǎn),并沒有標(biāo)明終點(diǎn),因此需要使用break使解釋器跳出switch語句或循環(huán)語句,否則程序?qū)?zhí)行下一個case。

關(guān)于循環(huán)

循環(huán)變量多是數(shù)字,下例為使用for循環(huán)來遍歷鏈表數(shù)據(jù)結(jié)構(gòu),并返回鏈表中的最后一個對象。

function tail(o) {
    for( ; o.next; o=o.next)
    return o
}

關(guān)于for in 循環(huán)

for(variable in object)
    statement
  • 解釋器先計算object表達(dá)式,如果表達(dá)式為null或者undefined,javascript解釋器回調(diào)過循環(huán)并執(zhí)行后續(xù)代碼。
  • 每次循環(huán)之前,都會計算variable表達(dá)式的值,并將屬性名復(fù)制給他。

break&containue

break labelname //適用于嵌套多層的循環(huán)
containue labelname //適用于嵌套的循環(huán)中,用以跳出多層次嵌套的循環(huán)體邏輯

當(dāng)break和標(biāo)簽一起使用的時候,程序?qū)⑻D(zhuǎn)到這個標(biāo)簽所表示的語句塊的結(jié)束,或者直接終止這個閉合語句塊的執(zhí)行。

try/catch/finally

try{
        //通常來講,這里的代碼不會出現(xiàn)問題
        //有時拋出一個異常,要么由throw語句直接拋出異常
        //要么通過調(diào)用一個方法間接拋出異常
}catch (e){
        //當(dāng)且僅當(dāng)try語句拋出異常,才會執(zhí)行的代碼
        //這里可以通過局部變量e來獲取error對象或者拋出的其他值引用
        //這里的代碼可以給予某種原因處理這個異常
        //可以通過throw重新拋出異常
}finally{
        //不管try語句塊是否拋出異常,這里的邏輯總是會執(zhí)行的,終止try語句塊的方式有
        //正常終止,執(zhí)行完語句塊的最后一條語句
        //通過break、containeu、return語句終止
        //拋出一個異常,異常被catch從句捕捉
        //拋出一個異常,異常未被捕獲,繼續(xù)向上傳播
}

try中產(chǎn)生的異常沒有catch進(jìn)行處理,就會先執(zhí)行finally之后,然后向上傳播這個異常,知道找到能處理這個異常的catch從句。

關(guān)于嚴(yán)格模式

  • 禁止使用with
  • 所有變量需要聲明
  • 調(diào)用函數(shù)中的this值為undefined,可以使用這個特性來檢測是否為嚴(yán)格模式
var hasStrictMode = (function(){
    "use strict";
    return this === undefined
}());

關(guān)于檢測對象

檢測集合中成員的所屬關(guān)系——判斷某個屬性是否存在于某個對象中。
可以通過in運(yùn)算符、hasOwnPreperty()和propertyIsEnumerable()方法來完成這個工作,甚至僅通過屬性查找也可以得到結(jié)果。
propertyIsEnumer(),當(dāng)屬性為自有的并且是可枚舉的,才會返回true。

檢測P是否是O的原型

`   p.isPrototypeOf(o);

關(guān)于序列化對象

對象序列化是指將對象轉(zhuǎn)換為JSON格式的字符串。

    JSON.stringify() //把對象撞換為字符串
    JSON.parse() //把JSON格式字符串轉(zhuǎn)換為對象

支持對象、數(shù)組、字符串、無窮大數(shù)字、bollen和null。
函數(shù)、RegExp、Error、undefined不能被序列化和還原。
NaN、Infinity的序列化結(jié)果是null。

關(guān)于toString()與toLocalString方法

在需要將對象轉(zhuǎn)換為字符串的時候,javaScript會調(diào)用這個方法。比如說遇上+時。默認(rèn)的該方法對于監(jiān)測對象十分有用。

var s = {x:1,y:2}.toString(); //返回的是[Object,Object]

  • Object的toLocalString方法,只是調(diào)用了toString而已。
  • Date和Number對toLocalString方法做了定制,可以用它對數(shù)字日期和時間做本地化的轉(zhuǎn)換
  • 數(shù)組元素的tolocalstring方法和toString方法很像,唯一的不同是每個數(shù)組元素會調(diào)用各自的tolocalstring完成字符串的轉(zhuǎn)換,而不是點(diǎn)用各自的tostring方法。

關(guān)于數(shù)組的聲明

var udf = [,,]  //數(shù)組的長度為2,原因是最后一個逗號可以省略也可以加上

關(guān)于稀疏數(shù)組

只包含從0開始的不連續(xù)索引的數(shù)組,即數(shù)組的長度大于數(shù)組元素的個數(shù)。

數(shù)組的長度

數(shù)組的長度是可配置的,通過改變數(shù)組的長度,刪掉相關(guān)的索引值。使得數(shù)組相關(guān)的push和shift方法不能使用。

數(shù)組的相關(guān)操作

Slice
當(dāng)出現(xiàn)負(fù)數(shù)的時候就是用數(shù)組的長度加上相應(yīng)的負(fù)數(shù),接收兩個參數(shù),第一個參數(shù)表示復(fù)制的起點(diǎn),第二個表示終點(diǎn)。
splics
接收三個參數(shù),操作位置,刪除個數(shù),插入元素,與concat不同,該方法接収元素而非數(shù)組
for-each

function foreach(a,f,t){
    try{ a.forEach(f,t)}
    catch(e) {
        if( e=== foreach.break) return;
        else throw e;
    }
}
foreach.break = new Error ("stopIteration");

reduce&reduceRight
接受兩個參數(shù)分別是在每一項(xiàng)上調(diào)用的函數(shù)和作為歸并基礎(chǔ)值。
提供給內(nèi)函數(shù)的四個參數(shù)分別是,此項(xiàng),下一項(xiàng),此項(xiàng)索引,以及數(shù)組。

檢測數(shù)組

    Array.isArray() //ECMAScript5之前
    instanceof 不準(zhǔn)
    //兼容3
    var isArray = function.isArray || fucntion(o){
        return typeof o ===="object" &&
        Object.prototype.toString.call(o) === "[object Array]";
    };

關(guān)于類數(shù)組

類數(shù)組的條件:

  • 自動更新length屬性
  • 設(shè)置length為一個較小值將截斷數(shù)組
  • 從Array.prototype中繼承一些有用的方法
  • 其類屬性為Array
    function isArrayLike(o) {
        if(o && 
            typeof o === 'object' &&
            isFinite(o.length) &&
            o.length >= 0 &&
            o.length === Math.floor(o.length) &&
            o.length < 4294967296++)
            return true
        else
            return false
    }

類數(shù)組的操作

    var a={'0':a, '1':b, '2':c, length:3};
    Array.prototype.join.call(a,"+")
    Array.prototype.map.call(a,function(x) {
        return x.toUpperCase();
    }) //["A","B","C"]

關(guān)于作為數(shù)組操作的字符串

字符串是不可變值的,只是可讀的,所以使用push、sort、reverse、splice等方法是無效的,BUT不會報錯。

關(guān)于數(shù)組的操作的分類

不改變數(shù)組值的 改變數(shù)組的值
forEach()等迭代方法 棧、隊列方法
reduce、reduceRight歸并方法 reverse
concat連接方法 splice
slice -----

關(guān)于函數(shù)的概念

  • 形參相當(dāng)于函數(shù)中定義的變量,實(shí)參是調(diào)用函數(shù)時傳入的參數(shù)。
  • javaScript中的函數(shù)是參數(shù)化的,函數(shù)定義的時候會包含 一個稱為形參的標(biāo)示符列表,這些參數(shù)在函數(shù)體重向局部變量一樣工作。
  • 每次調(diào)用還會擁有另一個值,本次調(diào)用的上下文——this。
  • 如果通過訪問對象方法調(diào)用函數(shù),this指向該對象。
  • javascript 的函數(shù)嵌套在其他函數(shù)中定義,他們就可以訪問他們被定義時所處的作用域中的任何變量,這意味這閉包。

關(guān)于函數(shù)定義

函數(shù)名稱--name

function name (arguments){
    coments
}

表達(dá)式定義函數(shù)只適用于它作為一個大的表達(dá)式的一部分,比如在賦值和調(diào)用過程中定義函數(shù)。函數(shù)表達(dá)式定義函數(shù)之前無法調(diào)用函數(shù),沒有函數(shù)聲明提升的過程。
如果一個函數(shù)定義表達(dá)式包含名稱,函數(shù)的局部作用域?qū)粋€綁定到函數(shù)對象的名稱,函數(shù)名稱將成為函數(shù)內(nèi)部的一個局部變量。

var f = function fact(x){
    if(x <= 1)
        return 1;
    else
        return x*fact(x-1); //在函數(shù)外部將不能訪問fact
}
fact(5); //fact is not defined

關(guān)于函數(shù)中的this

  • 當(dāng)函數(shù)作為方法調(diào)用,this指向的是擁有該方法的對象。
  • 當(dāng)函數(shù)作為函數(shù)調(diào)用,this指向的是全局對象,嚴(yán)格模式下為undefined。
  • 當(dāng)函數(shù)是構(gòu)造函數(shù),this指向構(gòu)造函數(shù)新創(chuàng)建的對象。
  • this不存在于作用域中,無法通過閉包的方式訪問,如需訪問可以把this的值付給你一個變量,使其存在于作用域中。
  • this無法被賦值。

構(gòu)造函數(shù)的return

  • 構(gòu)造函數(shù)一般沒有return
  • 顯示使用return 返回一個對象,這個對象會代替構(gòu)造函數(shù)創(chuàng)建的對象復(fù)制給new操作符左側(cè)的變量。
  • 如果return 為一個空語句或者返回值為原始值,那么這時將被忽略,同時把新生成的對象返回。

關(guān)于函數(shù)參數(shù)

  • 對于有需要的實(shí)參進(jìn)行判斷和賦值,對于可選參數(shù)使用/optional/來表示。
  • 對于不定實(shí)參函數(shù),實(shí)參個數(shù)不能為零。
  • Argument.callee指向正在執(zhí)行的函數(shù),可以使用這個來進(jìn)行函數(shù)內(nèi)部的解耦。
  • 使用傳入對象代替零散的參數(shù),避免多參數(shù)函數(shù)調(diào)用時參數(shù)位置與參數(shù)對應(yīng)的困難,提升語義性。
  • arguments.length (實(shí)際傳入的實(shí)參個數(shù))
  • arguments.callee.length(期望傳入的實(shí)參個數(shù))

關(guān)于用作命名空間的函數(shù)

利用作用域關(guān)系,定義一個函數(shù)用作臨時的命名空間,在這個命名空間里定義的變量不會污染全局作用域。

(function(){
    //coding
}());

第一個左側(cè)括號是必須的,否則解釋器會試圖將關(guān)鍵字function 解析為函數(shù)聲明語句。

關(guān)于閉包

  • 同一個作用域鏈中定義的兩個閉包,這兩個閉包共享同樣的私有變量。
function People(name){
    this.name = name;
    this.sayName = function(){name+=' hello';return name};
    this.sayNameAgain = function(){return name};
};
var lixinyue = new People('lixinyue');
lixinyue.sayName(); //lixinyue hello
lixinyue.sayNameAgain();//lixinyue hello
lixinyue.sayName();//lixinyue hello hello
lixinyue.sayNameAgain();//lixinyue hello hello
lixinyue.name //lixinyue
  • 關(guān)聯(lián)到閉包的作用域都是活動的,記住這一點(diǎn)非常重要。嵌套函數(shù)不會將作用域內(nèi)的私有成員復(fù)制一份,也不會對綁定的變量生成靜態(tài)快照。

  • 閉包無法訪問父級函數(shù)this和arguments,如果有這個需要在定義父級函數(shù)時就要將this和arguments賦給一個變量保存起來。

關(guān)于使用callapply

  • call和apply的第一個實(shí)參是要調(diào)用函數(shù)的母對象
  • 其后傳入的參數(shù)數(shù)組可以是真實(shí)數(shù)組也可以是類數(shù)組

關(guān)于bind()

  • bind方法不僅僅是將函數(shù)綁定至一個對象,他還把傳入的參數(shù)綁定到this??梢岳斫鉃榘押瘮?shù)的形參在用函數(shù)內(nèi)用綁定的值進(jìn)行賦值。
  • 因此bind返回的函數(shù)length,是原函數(shù)對象的形參個數(shù)減去bind綁定的實(shí)參個數(shù)。
  • 當(dāng)返回函數(shù)用于構(gòu)造函數(shù)時,其所創(chuàng)建的對象從原始的未綁定的函數(shù)對象中繼承prototype。

this 指針

  • 函數(shù)在被調(diào)用時,this指針是由調(diào)用者所決定的。
  • 直接調(diào)用時,this指針為Globel Object,瀏覽器端為window。
  • 方法調(diào)用時,this指針為方法所屬對象。如a.b.c(),this指針為a.b。
  • 構(gòu)造器調(diào)用時,解析器會創(chuàng)建一個Object,this指針為這個Object,默認(rèn)這個Object會被返回

apply或call可以通過第一個參數(shù)指定調(diào)用時的this指針。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,679評論 0 4
  • 第三章 類型、值和變量 1、存取字符串、數(shù)字或布爾值的屬性時創(chuàng)建的臨時對象稱做包裝對象,它只是偶爾用來區(qū)分字符串值...
    坤少卡卡閱讀 722評論 0 1
  • 迷霧森林的外圍,一個身穿青衫的貌美女子擦去臉上的血跡,這血跡并非是她的,而是她斬殺一只類似穿山甲的妖獸身上的。這...
    你說的對不是錯閱讀 315評論 0 0
  • 失戀最難熬莫過于千方百計,看書聽歌,聊天運(yùn)動。努力學(xué)習(xí)。然后以為自己放開了,灑脫了。前一秒還很愜意,還在認(rèn)真做事...
    CielWang閱讀 323評論 0 3
  • 我的眼淚越來越不聽話,總是不經(jīng)過大腦批準(zhǔn)就自己跑出來逛??赡苁且?yàn)槲业男囊膊宦牬竽X指揮了吧。 不...
    不棄的卡卡閱讀 258評論 2 0

友情鏈接更多精彩內(nèi)容