- 幻燈片的關(guān)鍵點(diǎn)需要完全看懂,把幾個(gè)點(diǎn)混在一個(gè)題里面
- 死記硬背的成分不太多,點(diǎn)比較小,文字長(zhǎng)串
- 填空的一些形式:給出程序,通過(guò)console.log()填空;
問(wèn)答有一題送分,要規(guī)整排版好,寫(xiě)上兩三個(gè)點(diǎn)就差不多了;
編程題會(huì)拿一些幻燈片的程序,看懂之后能重寫(xiě);
劃重點(diǎn)
運(yùn)行js ,值和類型,typeof(null)==object, 未被賦值的變量也是undefined,聲明數(shù)值中前后的0可以忽略,整數(shù)判斷,NaN不和自己等,字符串,模板字符串,轉(zhuǎn)義符,嵌入表達(dá)式,==obj混合考察==,delete操作符-權(quán)限,['key'],訪問(wèn)不存在的屬性-undefined-用什么方式判斷,內(nèi)置類,不加new,==數(shù)組混合==,==數(shù)組那幾個(gè)方法如slice==,‘use strict'不用管,先有雞,==變量作用域==,property帶記憶函數(shù),函數(shù)參數(shù)數(shù)目,==rest參數(shù),隱式參數(shù)==,bind,走神了漏了很多函數(shù)的沒(méi)看,global.this,==箭頭函數(shù)==,==運(yùn)行上下文==,閉包說(shuō)不用管,==詞法環(huán)境==題目多,obj的方法們,遍歷器很復(fù)雜,for of,spread,forEach,常識(shí)性方法們reduce,==屬性描述符==,類型轉(zhuǎn)換那一堆不用記但要理解,string->number(+),轉(zhuǎn)換那些會(huì)有題目,|| &&, ==, ===,五六講考不到,==頁(yè)面事件處理==,HTML和CSS看明白了就行,==定時(shí)器==,==事件傳播,處理,代理監(jiān)聽(tīng)==,==異步==分值多,setTimeout 讀文件 仿真怎么做 ==Generator==原理是函數(shù)運(yùn)行上下文,==Promise對(duì)象==catch等
基本語(yǔ)法與特性
一個(gè)變量同時(shí)只能引用一個(gè)值,一個(gè)值可同時(shí)被多個(gè)變量引用
-
一個(gè)==值只能具有一個(gè)類型==且不可改變,一個(gè)類型至少具有一個(gè)值
const :不改變變量和值之間的引用關(guān)系,原子類型的值不被改變,因此效果和常引用一致
-
js中的值有七種類型
所有原子類型的值在聲明后都不會(huì)發(fā)生變化
-
null
let a = null// 'undefined'
typeof a// 'object' 這是一個(gè)原生bug -
undefined
- 只有一個(gè)值undefined,聲明變量沒(méi)被賦值時(shí)被缺省賦值為undefined; 對(duì)未聲明變量的引用會(huì)得到錯(cuò)誤,但是typeof是可以的(let不行)
-
boolean
- 假 - N0fun : NaN, +0, -0, false, undefined,null,""(空字符串)
-
number
控制小數(shù)位數(shù)toFixed(),控制有效數(shù)字個(gè)數(shù)toPrecision()
數(shù)值相等判斷用=== (Number.EPS=2^-52)
NaN也是number,不和任何值相等,它是唯一不和自己相等的值
當(dāng)然復(fù)合類型判斷相等是看地址,所以{}!=={},[]!==[],function(){}!==function(){}-1/0 === -Infinity
2^ 969和1.79E308都還可以,多了就不大行了 ——數(shù)值范圍不用記
-
還有Object的方法is(a,b)編碼相等,isInteger(),isSafeInteger()其實(shí)就是2^53-1含以下
function is(v1,v2) { /*自己寫(xiě)判斷相等函數(shù)*/ if (v1 === 0 && v2 === 0) return 1/v1 === 1/v2 //+-0 if (v1 !== v1) return v2 !== v2 //NaN return v1 === v2 }
-
string
- ES采用UTF-16的編碼方式將string中的16位整數(shù)序列翻譯成字符
模板字符串前后要用
括起來(lái),可以嵌入表達(dá)式 以下顯示為s='Hi,3+4=7'let a = 3, b = 4;let s='Hi,${a}+$=${a+b}';` -
symbol:提供了一種存儲(chǔ)無(wú)關(guān)的方式來(lái)表達(dá)一個(gè)符號(hào)
初始動(dòng)機(jī)是為obj加入private property,而在實(shí)際使用中,這作為定制/擴(kuò)展系統(tǒng)功能的一種方式
-
創(chuàng)建/使用:
let mySymbol = Symbol("a description") //不準(zhǔn)用new let myObject = {} myObject[mySymbol] = "a property with a symbol key" let mySymoblObj = Object(mySymbol) //用函數(shù)封裝到obj里面 let mySymbol1 = Symbol(), mySymbol2 = Symbol() mySymbol1 === mySymbol2 //false 永遠(yuǎn)不相同- 共享Symbol類型的值:利用全局的symbol值注冊(cè)庫(kù)
let mySymbol = Symbol.for("description")
- 共享Symbol類型的值:利用全局的symbol值注冊(cè)庫(kù)
在for-in語(yǔ)句中,不會(huì)遍歷到obj里symbol類型的key
object(non-primitive type)
-
property(key~string/symbol,value,...)
在沒(méi)增加權(quán)限控制時(shí),可以逐步添加屬性
點(diǎn)操作符只能存取key不會(huì)導(dǎo)致歧義的屬性,而方括號(hào)都可以/*ES6 simplified object literal declaration*/ let name = "shellywhen", age = 20 let good$Girl = {name,age} /*former object literal declaration*/ let normal_Girl = {name: "shellywhen", age: 20} /*use a inner constructor*/ let girl = new Object() //"new" is neccessary girl.name = "shellywhen" girl.age = 20
-
-
- built-in obj
這和自動(dòng)裝箱(automatic-boxing)有關(guān),讓原子類型具有方法
ES規(guī)定,對(duì)Number/Boolean/String不加new就是強(qiáng)制類型轉(zhuǎn)換
超出Array長(zhǎng)度的賦值可能出現(xiàn)空洞(hole),可以修改length階段 - objects are truthy,如
new Boolean(false) == true
- built-in obj
-
傳值/傳引用?
根據(jù)ES規(guī)范中的文字描述,賦值語(yǔ)句/函數(shù)調(diào)用傳的都是==引用==。
-
一些build in object
-
Array
-
建立:
myList = ["dog", false, NaN]
myList=new Array("dog",false,NaN)new Array 參數(shù)只有一個(gè)整數(shù)時(shí),理解為整個(gè)數(shù)組長(zhǎng)度為該值
為避免邊界行為,使用Array.of()來(lái)傳入數(shù)組內(nèi)容 首末刪改:
pushpopunshiftshift(看字母數(shù))
中段刪改:splice(start, deleteCount, ...item)
取中段:slice(start = 0, end = length-1)
-
-
Function 既是constructor也是 b-i-o
let foo = new Function("a","b","return a+b")- typeof 一個(gè) function obj 返回"function"
-
Prototype
-
- 每個(gè)obj相關(guān)聯(lián)且僅關(guān)聯(lián)一個(gè)Prototype
- Prototype要么是obj要么是null值
ES規(guī)范規(guī)定,Prototype是obj的一種internal state,被存放在名為[[Prototype]]的internal slot中;
對(duì)于一個(gè)obj,包含properties, internal slots, internal methods
<img src="pic/ObjectComponent.png" style="zoom:30%"></img>obj之間通過(guò)prototype關(guān)系形成原型鏈,提升obj的動(dòng)態(tài)性
- 設(shè)置
創(chuàng)建時(shí)關(guān)聯(lián):let obj = Object.create(proto)
創(chuàng)建后關(guān)聯(lián):Object.setPrototypeOf(obj, proto)
獲得一個(gè)obj的prototype:let proto = Object.getPrototypeOf(obj)
-
特性
主函數(shù)可被理解為global object的一個(gè)property
無(wú)論在程序的什么位置,只要對(duì)未聲明變量賦值,改賦值語(yǔ)句一旦執(zhí)行后該變量自動(dòng)變?yōu)間lobal object的一個(gè)property
在源文件第一行寫(xiě)下"use strict"就能消滅js的常見(jiàn)邪惡特性
js在運(yùn)行前,通常有一個(gè)耗時(shí)幾微秒的編譯活動(dòng),變量的作用域在這個(gè)編譯活動(dòng)中形成。js更接近一種解釋型語(yǔ)言。從效果來(lái)看,編譯把作用域的變量聲明提到前面。==考點(diǎn)區(qū):var奇怪行為==
- 使用function declaration聲明的函數(shù)變量具有函數(shù)級(jí)(體)的作用域
- 使用let const聲明的變量具有塊級(jí)的作用域(從聲明處開(kāi)始)
Function
function是特殊類型的object,對(duì)object做的事情對(duì)function也能做——可以賦值給變量,放到數(shù)組中,作為property的value,<u>作為參數(shù)(callback function),作為返回值</u>,為function添加property
ES6為function添加了name這個(gè)property
數(shù)組的sort方法接收一個(gè)函數(shù),該函數(shù)接收兩個(gè)值,返回二者相對(duì)位置
數(shù)組的forEach方法接受一個(gè)回調(diào)函數(shù),該函數(shù)負(fù)責(zé)對(duì)每個(gè)元素逐個(gè)處理
let isPrime.store = isPrime.store || {} //使用或運(yùn)算符設(shè)置默認(rèn)值
函數(shù)參數(shù)
調(diào)用函數(shù)時(shí)傳遞的參數(shù)數(shù)量不需要等于定義時(shí)參數(shù)的數(shù)量
傳入一個(gè)數(shù)組,直接在數(shù)組前加...(叫做spread操作符)
-
參數(shù)默認(rèn)值(ES6引入)
let add = (a = 0, b = 0) => a+blet add = (a = 0, b = 1) => a+b console.log(add(b=2)) // 2
-
當(dāng)缺少參數(shù)時(shí),在函數(shù)體內(nèi)違背傳入的參數(shù)值為undefine
多傳入的參數(shù)在函數(shù)體內(nèi)通過(guò)arguments/rest參數(shù)(ES6引入)訪問(wèn)
rest是未定義的剩余參數(shù)數(shù)組,arguments是所有的參數(shù)對(duì)象let multimax = function(a, ...remainingNumbers) { remainingNumbers.sort((d1,d2)=>d1-d2) allArgument = Array.from(arguments) //ES6 轉(zhuǎn)成數(shù)組 return a * remainingNumbers[0] } console.log(multimax(3,8,1,7,6,5))let func = function(a,b) { //"use strict"可消除別名特性 let c = a console.log(arguments[0], a, c) a = 100 console.log(arguments[0], a, c) arguments[0]=10000 console.log(arguments[0], a, c) } func(1) -
調(diào)用
函數(shù)上下文 function context
-
- 每次函數(shù)調(diào)用,都會(huì)關(guān)聯(lián)一個(gè)特定的函數(shù)上下文,即一個(gè)object或undefined值,作為一個(gè)隱式參數(shù)被傳遞到函數(shù)體中,對(duì)應(yīng)的參數(shù)名稱是this
- 在非嚴(yán)格模式下,函數(shù)上下文為global object, 而在嚴(yán)格模式下函數(shù)上下文為undefine值
- 用以聯(lián)系起function和被賦值的property
new.target的值為undefined,則函數(shù)調(diào)用前沒(méi)有new,否則有
-
作為函數(shù)/方法調(diào)用:命名約定首字母小寫(xiě)
- 在原型鏈上的表現(xiàn) - 函數(shù)來(lái)自遠(yuǎn)方,而this始終是當(dāng)前對(duì)象
-
作為構(gòu)造函數(shù)調(diào)用:命名約定首字母大寫(xiě)
- 在前面加上new關(guān)鍵詞,以更加方便地創(chuàng)建多個(gè)具有足夠共性的obj
- 如果不return this則返回值正常返回,new創(chuàng)建的obj被忽略
-
通過(guò)apply或call方法調(diào)用
隨意調(diào)用函數(shù)時(shí)的函數(shù)上下文
-
x.call(thisArg, ...args)x.apply(thisArg, argArray)
第一個(gè)參數(shù)是調(diào)用函數(shù)上下文
第二個(gè)參數(shù)call是以列表表示的傳入?yún)?shù),apply要用數(shù)組
返回值是以thisArg為上下文,對(duì)x調(diào)用的返回值大概是申請(qǐng)了個(gè)symbol 關(guān)聯(lián)方法,最后再刪除
-
其他
- bind 方法
x.bind(thisArg, ...args)- 返回一個(gè)函數(shù),行為與x完全相同;上下文被固化為thisArg;
- ...args是綁定的參數(shù)
- bind 方法
-
箭頭函數(shù)
- 箭頭函數(shù)不能作為構(gòu)造函數(shù),也沒(méi)有this,arguments這兩個(gè)隱式參數(shù);
- 箭頭函數(shù)定義中出現(xiàn)的this參數(shù)在箭頭函數(shù)創(chuàng)建時(shí)固化為當(dāng)時(shí)環(huán)境中的this參數(shù),永不再變;==function context==
-
閉包
- 當(dāng)?個(gè)函數(shù)對(duì)象被創(chuàng)建時(shí),同時(shí)還創(chuàng)建了?個(gè)閉包
其中包含: 該函數(shù)、以及在此時(shí)可以訪問(wèn)到的所有變量 - 用途是信息封裝,只用函數(shù)才能調(diào)用
- 實(shí)現(xiàn)方式:function execution context & lexical environment
- FEC: 每一次函數(shù)調(diào)用,通常會(huì)創(chuàng)建一個(gè)新的函數(shù)上下文
函數(shù)調(diào)用結(jié)束后,運(yùn)行上下文通常會(huì)被拋棄
ES程序的運(yùn)行會(huì)形成由“函數(shù)運(yùn)行上下文”構(gòu)成的棧 - 詞法環(huán)境是專門(mén)為閉包設(shè)計(jì)的,無(wú)法顯式訪問(wèn)
由代碼塊和函數(shù)構(gòu)成,代碼片段的每一次運(yùn)行都會(huì)創(chuàng)建新的詞法環(huán)境 - 當(dāng)一個(gè)函數(shù)被創(chuàng)建時(shí),創(chuàng)建這個(gè)函數(shù)的代碼片段所關(guān)聯(lián)的詞法環(huán)境會(huì)被放到[[Environment]]的internal slot中;
當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),一個(gè)函數(shù)運(yùn)行上下文被創(chuàng)建壓到棧頂,同時(shí)為函數(shù)運(yùn)行上下文創(chuàng)建一個(gè)詞法環(huán)境,將該詞法環(huán)境的外層詞法環(huán)境設(shè)為該函數(shù)[[Environment]]的值
- FEC: 每一次函數(shù)調(diào)用,通常會(huì)創(chuàng)建一個(gè)新的函數(shù)上下文
- 當(dāng)?個(gè)函數(shù)對(duì)象被創(chuàng)建時(shí),同時(shí)還創(chuàng)建了?個(gè)閉包
<img src="pic/ExecuteNow.png" style="zoom:60%">
Object
-
常見(jiàn)方法:
key in obj - 尋找指定的key在不在這個(gè)obj上,或者對(duì)應(yīng)原型鏈上
.hasOwnProperty(key) - 尋找這個(gè)key在不在這個(gè)obj上
.getOwnPropertyNames(obj) 返回?cái)?shù)組,包含obj所有string類型的key
.getOwnPropertySymbols(obj) 返回?cái)?shù)組,包含obj所有symbol類型的key
-
Iterable object:
具有一個(gè)key為Symbol.iterator的屬性,這個(gè)屬性的值是一個(gè)函數(shù),函數(shù)會(huì)返回一個(gè)iterator;包括Array, Map, Set, String, auguments- iterator是一個(gè)object,具有next方法,對(duì)它的一次調(diào)用返回一個(gè)obj{done, value}
- for-of 循環(huán)語(yǔ)句(value)
-
Collections: Array, Map, Set
任何可遍歷的obj都可以傳到new里面構(gòu)造-
Array:
push, pop, unshift, shift, splice(start,num,...insert), slice(start,end), indexOf(value), LastIndexOf(value), findIndex(滿足條件), sort((v1,v2)=>{return v1<v2? -1: (v1>v2? 1:0)})
splice和slice都是返回start~end的東西
-
forEach((v,i,owner)=>{}) 是接受三個(gè)參數(shù)的;
map接收回調(diào)函數(shù),按順序?qū)γ總€(gè)值應(yīng)用該函數(shù)將這個(gè)值變成另一個(gè)值放進(jìn)新數(shù)組
every, someconst pets=[{name:'dog'},{name:'cat'},{name:'snake'}] if pets.every(pet=>'name' in pet) const names=pets.map(pet=>pet.name) // names=['dog','cat','snake']find找到第一個(gè)為止,filter把所有滿足的放進(jìn)數(shù)組
-
reduce
const num = [1,2,3,4,5] const sum = num.reduce((sum,v)=>sum+v, 0)
Map: 任何類型的值都能作為key
-
set(key,value),get(key),size,has(key),delete(key),clear(),forEach((value,key,owner)=>{})
-
Set: 由無(wú)重復(fù)值形成的有序列表
-
add(value),size,has(value),delete(value)
-
-
-
Property Descriptor
一個(gè)object,其中包含若干property,用于對(duì)所在property行為進(jìn)行描述;使用defineProperty(obj,propKey,propDes)來(lái)修改<img src="pic/PropertyDescriptor.png" style="zoom:60%">
==考點(diǎn)==:configurable被置為假,在writable為true時(shí)要么可以改false要么改值,其他均不行
- 通過(guò)getter和setter訪問(wèn)property
Prototype
-
- constructor提供了基于obj引用constructor的方法
在Javascript語(yǔ)言中,要是想仿真C++類的關(guān)系中,使用原型鏈的方式可以實(shí)現(xiàn)。==考點(diǎn):理解例子==
?
- class
const Person = function(name) { this.name = name } Person.prototype.getName = function() { return this.name } //Person關(guān)聯(lián)的object加入一個(gè)函數(shù) const xie = new Person("shelly") console.log(xie.getName()) //xie->對(duì)象->[[Prototype]]有這個(gè)函數(shù)
class Person { constructor(name) { this.name = name } getName() { return this.name } }- extends
class Mammal {} class Person extend Mammal (){ constructor() { // ... } getWeight() { return super.getWeight } }- instanceof: 判斷一個(gè)obj是否在某個(gè)構(gòu)造函數(shù)的原型鏈上
析構(gòu)操作
-
一些例子
/*對(duì)Object的析構(gòu)*/ let node = { type: "identifier" name: "foo" loc: { start:{ line: 1 coloum: 2 } } range:[startIndex] } let {type, name} = node //要有=,不能=undefined/null ({type, name} = node) //提取obj型函數(shù)參數(shù)的特定property let {name: localname = "bar"} = node //缺省 不同名 let {loc:{start:{line}}, range:[startIndex]} = node /*對(duì)Array的析構(gòu)*/ let colors = ["red", undefined,"blue",["pink","yellow"]] let [1st, 2ed = "grey"] = colors let [, , 3rd] = colors let [,,,[,4in]] = colors //"yellow" let [5th, ...rest] = colors /*變量值交換*/ let [1st, 2ed] = [1st, 2ed] /*優(yōu)秀例子*/ function setCookie(name, value, {secure, path} = {}){ secure = 1 - secure }
-
類型轉(zhuǎn)換
這節(jié)太復(fù)雜了,自己看課件算了
很多時(shí)候,javascript會(huì)以顯式/隱式的方式將一種類型的值轉(zhuǎn)換為另一種類型的值;ES6定義了一組抽象操作;
- 一組抽象操作(看課件,內(nèi)容過(guò)多)
- ToPrimitive(input, preferredType)
- OrdinaryToPrimitive(input, prefferedType)
- ToBoolean(input) - N0fun
- ToNumber
- ToString
- ToObject
- ?
- && || 的行為
- == 抽象相等,比較過(guò)程中允許類型轉(zhuǎn)換; ===嚴(yán)格相等,比較過(guò)程中不允許進(jìn)行類型轉(zhuǎn)換。
Web頁(yè)面編程
Html內(nèi)容, CSS形式, JavaScript行為 -> DOM樹(shù)
-
元素選擇和修改
`preventDefault()` 防止href為空時(shí)的跳到新頁(yè)面的缺省行為getElementByIdgetElementsByTagNamegetElementsByClassName
document.addEventListener("DOMContentLoaded",()=>{
const div = document.querySelector("div")
console.log(div.style)
})
? getAttribute setAttribute(attr,value)
? CSS信息以嵌入式或鏈接式樣式表中的信息時(shí)無(wú)法直接從元素中獲得
? window.getComputedStyle(ele).getPropertyValue(propNameStr)
? 對(duì)于樣式表里面的內(nèi)容加入 !important 可提高優(yōu)先級(jí),避免被改動(dòng)
[Web頁(yè)面的事件處理流程] 當(dāng)處理完一個(gè)宏任務(wù)后,會(huì)立刻按序處理所有的微任務(wù),知道所有微任務(wù)都被處理完后才會(huì)處理下一個(gè)宏任務(wù);如果可能,瀏覽器會(huì)確保每秒60幀,一個(gè)宏任務(wù)及其所產(chǎn)生的微任務(wù)應(yīng)能在16ms完成
-
定時(shí)器
const id = setTimeout(func,delay)延遲delay毫秒把事件加入函數(shù)隊(duì)列setInterval(func,delay)每間隔delay毫秒便嘗試將事件加入函數(shù)隊(duì)列,當(dāng)任務(wù)隊(duì)列中還存在未處理的同源interval事件時(shí)interval對(duì)應(yīng)函數(shù)時(shí)不會(huì)加入隊(duì)列clearTimeout(id)函數(shù)尚未被觸發(fā)時(shí)取消定時(shí)器行為 -
Web頁(yè)面中的事件處理
處理計(jì)算密集型操作
-
事件在DOM中的傳播:默認(rèn)捕獲從外向內(nèi),冒泡從內(nèi)向外。
-
addEventListener(type,func,useCapture)
useCapture默認(rèn)是假,事件冒到它才會(huì)調(diào)用,否則監(jiān)聽(tīng)了就調(diào)用了const tb = document.querySelector("tbody") tb.addEventListener("click",function(e)){ if(e.target.tagName.toLowerCase()=="td") e.target.style.backgroundColor = "yellow" } //e.target是事件發(fā)生在的html元素
-
- 自定義事件
const Myevent = new CustomEvent(eventType, {detail: eventDetail})
- 自定義事件
Js異步編程
-
如果一個(gè)任務(wù)處理函數(shù)用時(shí)過(guò)長(zhǎng),會(huì)降低整個(gè)應(yīng)用的并發(fā)程度或處理效率。為了提高程序的并發(fā)程度或處理效率,需要異步編程。情境:計(jì)算密集,IO密集。
- 將計(jì)算密集型任務(wù)拆分為一組細(xì)粒度的子任務(wù)(例如表格拆分定時(shí)創(chuàng)建,在完成一個(gè)子任務(wù)后,把下一個(gè)子任務(wù)加入任務(wù)隊(duì)列
setTimeout(nextTask,0)) - 使用異步讀取文件或異步接收網(wǎng)絡(luò)數(shù)據(jù)的函數(shù)。在啟動(dòng)IO任務(wù)時(shí)傳入回調(diào)函數(shù);然后程序不必阻塞等待IO任務(wù)完成,而是繼續(xù)執(zhí)行后面的代碼。當(dāng)IO任務(wù)完成后,把IO完成事件加入任務(wù)隊(duì)列。
- 將計(jì)算密集型任務(wù)拆分為一組細(xì)粒度的子任務(wù)(例如表格拆分定時(shí)創(chuàng)建,在完成一個(gè)子任務(wù)后,把下一個(gè)子任務(wù)加入任務(wù)隊(duì)列
-
Generator函數(shù)
- 把函數(shù)本身做的事分為小的塊,由關(guān)鍵詞
yield來(lái)控制。 - 可以視為一個(gè)狀態(tài)機(jī)。
- return的值存在遍歷器的value里面。
function * likes(){ while(true) yield "likes" } function * PersonGenerator(){ yield "shelly" yield * likes() yield "gary" } for (let person of PersonGenerator()) console.log(person)與Generator函數(shù)進(jìn)行雙向通訊
- 通過(guò)next()從generator函數(shù)獲得數(shù)據(jù),通過(guò)next()的參數(shù)向generator傳入數(shù)據(jù)
-
- 向generator函數(shù)拋入異常;
let [a,b,c]=yield "hello" let rst =
- 把函數(shù)本身做的事分為小的塊,由關(guān)鍵詞
Promise對(duì)象