JavaScript權威指南筆記(上)-語言核心

詞法結構

字符集

使用Unicode編寫

  • ES3 Unicode2.1+
  • ES5 Unicode3+

區分大小寫

註釋

// 註釋

/*
註釋
*/

標識符和保留字

必須以字母、下劃線、美元符開始,後續字符可以是字母、數字、下劃線、美元符,即數字不能作爲首字符

保留字

QQ瀏覽器截圖20181126125600
QQ瀏覽器截圖20181126125600
QQ瀏覽器截圖20181126125655

可選的分號

Javascript只有在缺少了分號就無法正確解析代碼的時候纔會填補分號。

一般,一條語句以(、[、/、+、-開始,它極有可能和前一條語句一起解析。return、break、continue除外

類型、值和變量

數據類型:在編程語言中、能夠表示並操作的值的類型

變量:一個值的符號名稱,可以通過該名稱獲得值的引用。

數據類型

一般分類

  • 原始類型:數字、字符串、布爾值、null、undefined
  • 對象(屬性的鍵值對集合)類型:數組、普通對象、函數類、日期類、正則類、錯誤類

其他分類

  • 可以擁有方法的類型和不能擁有方法的類型
  • 可變類型(數字、布爾值、null、undifined、字符串)和不可變類型(對象、數組)

數字

javascript採用IEEE 754標準定義的64位浮點格式表示數字,最大值±1.7976931348623157E+308,最小值±5E-324

能夠表示的整數範圍爲-2E+53~2E+53。實際操作(如數組索引)是基於32位整數。

注意: 小數精度問題,如0.1+0.2 != 0.3 ,需要轉成整數計算,計算完成再轉回小數。產生原因是Number採用的時IEEE 754 64位雙精度浮點數編碼,浮點數無法精確表示其值範圍內的所有數值,導致十進制轉換成二進制時有舍入模式,產生了誤差

格式

  • 整形直接量
  • 浮點直接量

算術運算

上溢出(正負無窮)使用±Infinity表示,下溢出(無限接近於0)則返回0(±0)。

NaN和任何值都不相等,包括自身。

二進制浮點數和四捨五入錯誤

在javascript使用實數時,常常只是真實值的一個近似表示。

let x=0.3-0.2
let y=0.2-0.1
x==y // false
x==0.1 // false
y==0.1 // true
// 由於舍入誤差,0.3和0.2之間的近似差值實際上不等於0.2和0.1之間的近似差值

文本

字符串是一組由16位值組成的不可變的有序序列。字符串長度是其所含的16位值的個數。

轉義字符

微信截圖_20181126223425

布爾值

true或者false
可轉換爲false的值:undefined、null、0、-0、NaN、''。

null和undifined

  • typeof null爲object,含義爲非對象
  • undifined 未定義值

全局對象

全局屬性、全局函數、構造函數、全局對象

包裝對象

存取字符串、數字或布爾值的屬性時創建的臨時對象叫包裝對象。
微信截圖_20181126223425

不可變的原始值和可變的對象引用

可變類型(數字、布爾值、null、undifined、字符串)和不可變類型(對象/引用類型、數組)。

類型轉換

微信截圖_20181126223425

轉換和相等性

微信截圖_20181126223425

顯式類型轉換

微信截圖_20181126223425
微信截圖_20181126223425
微信截圖_20181126223425
微信截圖_20181126223425
微信截圖_20181126223425
微信截圖_20181126223425

變量聲明

如果給一個未聲明的變量賦值(不可配置),實際上會給全局對象創建一個同名屬性(可配置),不建議這樣用。

創建一個全局變量實際上是給全局對象創建了一個屬性。

變量作用域

一個變量的作用域是程序源代碼中定義這個變量的區域。

  • 函數作用域、塊級作用域。
  • 聲明提前

類型檢測

  • typeof 用於基礎類型和函數判斷
  • instanceof用於對象類型判斷
  • Object.prototype.toString.apply([])==='[object Array]' null、undifined失效

表達式和運算符

表達式

表達式分爲簡單表達式(常量、變量名)和複雜表達式(由簡單表達式組成)。

原始表達:

表達式的最小單位,

  • 直接量(包括:數字、字符串、布爾,不包括數組、對象)
  • 關鍵字
  • 變量

由簡單表達式可以組合成複合表達式

複雜表達式

  • 對象和數組的初始化表達式
  • 函數定義表達式
  • 屬性訪問表達式
  • 調用表達式
  • 對象創建表達式

運算符

說明:

  • 下圖按照優先級高到低排序,水平線分割的具有不同的優先級
  • A列表示運算符結核性,L(左到右) R(右至左)
  • N列表示操作數的個數
  • 類型列表示期望的操作數類型以及運算符的結果類型

QQ瀏覽器截圖20181127131052
QQ瀏覽器截圖20181127131052

分類

按照操作數個數分:一元(+1)、二元(1+2)、三元(?:)

左值

表達式只能出現在賦值運算符的左側。變量、對象屬性、數組元素均是左值。

算術表達式

一元算術運算符

作用於一個單獨的操作數,併產生一個新值,具有很高的優先級,且均爲右結合。

  • +:轉換爲數字或者NaN,並返回轉換後的值
  • -:和+一樣,但是會改變結果的符號。
  • ++--:運算符在操作數前,操作數±1並返回計算後的值;運算符在操作數之後,操作數±1,並返回計算前的值。
  • ,逗號運算符,從左到右一次執行,返回最右邊的值

關係表達式

  • in
  • instanceof

邏輯表達式

賦值表達式

其他運算符

  • ?:
  • typeof
  • delete
  • viod
  • ,逗號運算符,從左到右計算,最後返回最右邊的值

語句

聲明語句

  • 變量var let
  • 函數function

條件語句

switch

switch(expression){
    statements
}
// expression中計算是使用===

循環

do/while

do{
   statements 
} while(expression)
// 至少執行一次

for/in

// 將對象中的所有屬性複製到一個數組中
var o = {x:1,y:2,z:3};
var a = [], i = 0;
for(a[i++] in o) /* empty */;

跳轉

標籤語句

mainloop: while(token I= null) { 
// 忽略這裏的代碼...
continue mainloop; //跳轉到下一次循環
// 忽略這裏的代碼...
}
//從標籤名開始,以便在報錯時退出程序
compute_sum: if (matrix) { 
    for(var x = o; x < matrix.length; x++) { 
        var row= matrix[x]; 
        if (!row) break compute_sum; 
        for(var y = o; y < row.length; y++) { 
            var cell= row[y]; 
            if (isNaN(cell)) break compute_sum; sum+= cell; 
        }
    }
    success= true; 
}
// break語句跳轉至此II如果在success== false的條件下到達這裏, 說明我們給出的矩陣中有錯誤//否則將矩陣中所有的元素進行求和

其他語句類型

width

// 臨時擴展作用域鏈
with(document.form[0]){
    name.value=""
}

try/catch

try{
    xxxx
}catch(e){
    xxx
}finally{
    xxx
}

對象

創建對象

  • 對象直接量創建的對象原型爲Object.prototype
  • 通過new創建的對象原型爲使用的原構造函數的prototype
  • Object.create()創建的對象原型爲第一個參數,也可設置爲null

屬性的查詢和設置

屬性訪問錯誤

查詢屬性和原型有關,設置與原型無關(如果設置屬性爲繼承屬性,且具有setter方法時,將執行setter,而不是給當前對象創建新的屬性)

下列情況給對象O設置屬性P會失敗

  • O中屬性P是隻讀的(defineProperty()方法中有例外)
  • O中的P是繼承的,且是隻讀的
  • O中不存在屬性P,O中沒有使用setter方法繼承屬性P,並且O的可擴展性()是false

檢測屬性

  • in:x in o
  • hasOwnProperty: O.hasOwnProperty(x)
  • propertyIsEnumerable: o.propertyIsEnumerable(x),hasOwnProperty的增強版,自身屬性且可枚舉
  • o.x!==undefined x的值爲undefined則需要使用in

屬性的特性

  • 值 value
  • 可寫性 writable
  • 可枚舉性 enumerable
  • 可配置性 configurable
獲取自身屬性的特性
Object.getOwnPropertyDescriptor({x:1},'x')
// 返回{value:1,writable:true,enumerable:true,configurable:true}
設置屬性的特性
// 單個
Object.definePeoperty(o,'x',{
    value:1, // 值
    writable:true, // 可讀
    enumerable:true, // 可遍歷
    configurable:true // 可改變配置
})
// 批量
Object.definePeoperties(o,{
    x:{
        value:1,
        writable:true,
        enumerable:true,
        configurable:true
    },
    y:{
        value:1,
        writable:true,
        enumerable:true,
        configurable:true
    }
})

對象的三個屬性

原型

  • 查詢原型Object.getPrototypeOf()
  • 檢測是否包含某個原型p.isPrototypeOf(o),p是否是o的原型

類屬性

可以通過toString獲取對象的類屬性

function classof(o){
    if(o===null) return 'Null';
    if(o===undefined) return 'Undefined';
    return Object.prototype.toString.call(o).slice(8,-1);
}
classof({}) // => 'Object'

可擴展性

  • 查詢可擴展性 Object.isExtensible(o)
  • 轉換成不可擴展 Object.preventExtensions(o)
  • 封閉:轉換爲不可擴展且所有屬性不可配置 Object.seal(),可使用Object.isSealed()來檢測是否封閉
  • 凍結:轉換爲不可擴展且所有屬性不可配置、所有屬性只讀 Object.freeze(),可以使用Object.isFrozen()來檢測是否凍結

序列化

JSON.stringify(),JSON.parse()具可接受第二個參數,標識需要序列化或還原的屬性列表

對象方法

  • toJSON()
  • valueOf()將對象轉換成原始值

數組

創建數組

  • 數組直接量[],該語法有可選的結尾逗號,故[,,]只有兩個元素而非三個
  • new Array()
new Array() // 創建一個空數組
new Array(10) // 創建一個長度爲10的數組
new Array(5,4,3) // 創建一個已包含數組元素數組

稀疏數組

稀疏數組並不是項的值爲undefined,而是不存在

// 三種方式創建
// 1
new Array(5)
// 2
a=[]
a[1000]=0
// 3
delete 

數組方法

*標識爲變異方法

  • join
  • reverse *
  • sort *
  • concat
  • slice
  • splice *,返回刪除元素組成的數組
  • push/unshift *,返回數組新的長度
  • pop/shift * 返回刪除元素的值
  • toString/toLocalString 無方括號,逗號分隔
  • forEach
  • map
  • filter,可以使用來壓縮稀疏數組
  • every 所有元素調用判定函數,均返回true才返回true
  • some 所有元素調用判定函數,有一個返回true就返回true
  • reduce/reduceRight
// 求和、第二個參數爲temp的初始值,不傳默認使用數組中的第一個元素
arr.reduce((temp,value,index,arr)=>temp+value, 0)
  • indexOf/lastIndexOf

數組類型

判斷使用Array.isArray(arr)判斷是否是數組

函數

構造函數:用於初始化一個新創建的對象的函數

函數定義

兩種定義方式及區別:

  • 函數聲明語句,可以在定義前使用(函數聲明前置);不能出現在循環、條件、try/catch/finally、with中
  • 函數定義表達式,不能在定義前使用(變量聲明前置);可以出現在任何地方
  • 函數構造器

QQ瀏覽器截圖20181202215231

函數調用

四種調用方式:

  • 作爲函數:this在非嚴格模式爲全局對象,嚴格模式爲undefined
  • 作爲方法:this爲方法所屬對象
  • 作爲構造函數:this爲新構造的對象
  • call()或者apply()間接調用:this爲指定的對象

函數的實參與形參

不定實參函數:可以接收任意個數的實參,通過arguments(類數組對象)接收參數

作爲命名空間的函數

立即調用函數

(function(){
    
}())

閉包

微信截圖_20181202221449
微信截圖_20181202221059
詞法作用域,函數內變量作用域是在函數定義時創建的,而不是在調用時創建,且在函數執行時,定義時的作用域鏈依然有效。
函數對象可以通過作用域鏈相互關聯起來,函數體內部的變量都可以保存咋子函數作用域內,這種特性叫閉包。

函數屬性、方法和構造函數

length 形參個數

arguments 參數對象(類數組對象)

prototype 指向原型對象

apply、bind、call

  • apply 將函數作爲指定對象thisObj的方法來調用,傳遞給它的是指定的參數數組args
function.apply(thisObj,args)
  • call 將函數作爲指定對象thisObj的方法來調用,傳遞給它的是指定的參數,如果thisObj爲null,則爲全局對象
function.call(thisObj,arg1,arg2,...)
  • bing 返回一個新函數,通過可選的指定參數,作爲指定對象obj的方法調用該方法,傳遞給該函數的參數由兩部分組成,一部分是傳遞給bind()的args數組指定的參數,剩下的是傳給這個新函數的所有值。

傳入bind()的實參都是放在傳入原始函數的實參列表開始的位置。

function.call(obj,arg1,arg2,...)
// 示例:
let g=f.bind(obj,1,2)
g(3)
// 等價於
f.call(obj,1,2,3)

toString

Function()構造函數,最後一個實參爲函數體

函數式編程

高階函數

操作函數的函數,接收一個或者多個函數作爲參數,並返回一個函數。
微信截圖_20181126223425

不完全函數

傳入bind()的實參都是放在傳入原始函數的實參列表開始的位置。

作用域

分類

  • 全局
  • 函數,塊級(ES6+)
  • eval

作用域鏈

變量對象

用於存儲執行上下文中的:

  • 變量
  • 函數聲明
  • 函數參數
1.變量初始化階段

QQ瀏覽器截圖20181202223314

2.代碼執行階段

類和模塊

特性:封裝、繼承、多態、抽象

類名使用大駝峯命名。ES6直接使用class,下面是ES6之前的。
QQ瀏覽器截圖20181128130544

構造函數和類的標識

原型對象是類的唯一標識:當切僅當兩個對象繼承自同一個原型對象時,它們才屬於同一個類的實例。

construsctor

構造函數是類的公共標識,construsctor屬性爲對象提供了類。

let 0= new F()
0.construsctor===F // => true

QQ截圖20181130130049

javascript中的java式的類繼承

TIM截圖20181202165528
創建一個類分爲三步:

  • 定義一個構造函數,並設置初始化新對象的實例屬性
  • 給構造函數的prototype對象定義實例方法
  • 給構造函數定義類字段和類屬性

類的擴充

javascript中基於原型的繼承機制是動態的,如果創建對象之後原型的屬性發生變化,也會影響到繼承這個原型的所有實例,即我們可以通過給原型對象添加方法來擴充Javascript類。

類和類型

instanceof:
obj instanceof c 
obj.isPrototypeOf(f)
constructor:
x.constructor===Number
構造函數的名稱
Object.prototype.toString.call(o)

注意:

  • 前兩種方法在多個執行上下文無效
  • 這三種方法都有一個問題,就是不是所有對象都有constructor屬性
鴨式辯型

Javascript中的面向對象技術

標準轉換方法

  • toString()
  • toLocaleString()
  • valueOf()
  • toJSON()

方法借用

Object.prototype.xxx=xxx

子類

  • 方法鏈
  • 構造函數鏈

正則表達式的匹配模式

定義

  • 直接量
  • 構造器

內容

直接量字符

QQ瀏覽器截圖20181128124924

字符類

QQ瀏覽器截圖20181128125033

重複

非貪婪重複在匹配字符後加一個?即可。
QQ瀏覽器截圖20181128125033

選擇、分組、引用

QQ瀏覽器截圖20181128125325

指定匹配位置

QQ瀏覽器截圖20181128125414

修飾符

QQ瀏覽器截圖20181128125434

String方法

  • search
  • replace
  • match
  • split

RegExp對象

屬性:
  • source
  • global
  • ignoreCase
  • multiline
  • lastIndex
方法:
  • exec
  • test

javascript的子集和擴展

迭代

迭代器

Iterator(),返回迭代器

for(let [k,v] in Iterator({a:1,b:2}))
console.log(k+"="+v)   // a=1,b=2

特性:

  • 只針對自有屬性進行遍歷,忽略繼承屬性
  • 第二個參數傳true,則只遍歷屬性名。忽略值

數組推導*

[expression for (varuable in object) if(conditon)]

函數簡寫

表達式閉包:如果函數只計算一個表達式並返回它的值,關鍵字return和花括號可以省略

let succ=function(x)x+1

多catch從句

E4X

jsx語法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章