ES6的類數組array-like對象
聲明
- var 數組名稱=[元素1,元素2,元素3...];
- var aList = new Array( 1,2,3 );
- var aList = [ ]
- 給數組添加元素的另一種方式:數組名[索引]=元素
特性
- 可以存儲不同的數據類型的元素。
- 數組的長度可變。
- 數組的索引可以是數字,也可以是字符串。
- 可以多層嵌套
方法
Array.concat() #連接數組
Array.join() #將數組元素連接起來以構建一個字符串
Array.pop() #刪除並返回數組的最后一個元素,對比delete
Array.push() #給數組添加元素,同[length]=obj
Array.reverse() #顛倒數組中元素的順序
Array.shift() #將元素移出數組
Array.slice() #返回數組的一部分
Array.sort() #對數組元素進行排序
Array.splice() #插入、刪除或替換數組的元素
Array.unshift() #在數組頭部插入一個元
ES6中的邏輯判斷語句
JavaScript 運算符
- 算數運算符: + - * % / ++ -
- 賦值運算符: = += -= *= /= %=
- 比較運算符: == === != !== > < >= <=
- 邏輯運算符: && || !
- 判斷: fasle undefined null 0 NaN 空字符串
- 條件運算符: if...else (a === b)?x:y
循環語句
- break語句
- continue語句
- do...while語句: 一直重復,直到條件為假(false),至少執行一次
- while語句: 條件為真(true)就一直執行 可能一次不執行
- switch (val){case a: xxx; break; ...}
- for 語句
- for...in語句
- for ... of 語句
- 在可迭代對象上創建了一個循環
- 注意 for...in 和for ...of 的區別
- for...in循環讀取鍵名,for...of循環讀取鍵值
- 數組,set,map,對象,字符串
ES6中的函數與方法
聲明
-
一般function:
name ([param[, param,[..., param]]]) { [statements] } -
匿名函數(立即執行):
(function(){}())這樣寫的好處是在內部定義的變量不會跟外部的變量有沖突,達到保護內部變量的作用
(function(name){
console.log(`Hi$(name)`);
})('riy')
運行(執行,調用)
- 立即執行函數表達式 IIFE (Immediately Invoked Function Expression)
- 賦給一個變量
var sayHi = function(name){
console.log(`Hi ${name}!`);
}
- 賦給對象屬性
var obj= {}
obj.sayHi = function(name){
console.log(`Hi ${name}!`); //Hi Riy!
}
obj.sayHi('Riy')
// --------------------- //
obj.upperHi = function(){
return this.name.toUpperCase()
}
obj.name = 'Riy'
console.log(obj.upperHi()); //RIY
- 作為參數傳遞給另一個函數(高階函數)
let arr = [1,2,3,4,5]
let newArr = arr.map(function(x){return x*2});
console.log(newArr); //[2,4,6,8,10]
let andArr = arr.reduce(function(x, y){return x*y})
console.log(andArr); //120
- 將函數作為返回值
function calcArea(w, h){
return w*h
}
function rectInfo(w, h){
console.log(`w=${w} h=${h}的面積為`);
return calcArea;
}
var w = 4;
var h = 5;
area = rectInfo(w,h)(w,h);
console.log(area); //20
函數的參數
- 形式參數
- 默認參數
function user(name, password='123456'){
if(password == '123456'){
return name+' OK'
}else{
return name+' error'
}
}
var res1 = user('riy')
console.log(res1); //riy OK
- 剩余(rest)參數
function sum(a, b){
console.log(arguments); //arguments是一個對應於傳遞給函數的參數的類數組對象。
return a+b
}
a = sum(4, 8)
console.log(a); //12
function newSum(...all){
console.log(all); //document.all實質就是文檔中所有元素的集合。可以看做一個數組。
return all[0]+all[1]
}
b = newSum(4, 8)
console.log(b); //12
函數的屬性和方法
- name
- length
- toString()
function sum(){};
var otherSum = sum;
otherSum(1,2,3,4)
console.log(otherSum.name); //sum
console.log(sum.length) //0
console.log(sum.toString()); //function sum()
ES6的變量解構賦值與作用域
解構賦值
作用域
-
全局變量:
在函數之外定義的變量,函數內部可以訪問 -
局部變量:
在函數內部定義的變量,只能在函數內部訪問,外部無法訪問 -
全局作用域(Global Scope)
- 最外層函數和在最外層函數外面定義的變量擁有全局作用域
- 所有末定義直接賦值的變量自動聲明為擁有全局作用域
- 所有 window 對象的屬性擁有全局作用域
- 局部作用域(Local Scope)-函數作用域
- 定義了一個函數的同時,就創建了一個函數作用域
- 內部定義的變量不能在函數外部訪問
- 嵌套的作用域變量從當前作用域往上尋找聲明,找不到則報錯
- 函數執行時所在的作用域,是定義時的作用域,而不是調用時所在的作用域
- 全局和局部作用域的關系
- 在函數體內,局部變量的優先級高於同名的全局變量
- 定義在全局域中的函數可以訪問所有定義在全局域中的變量
- 塊級作用域
關於let:
- let聲明的變量只在代碼塊有效
- let聲明的變量不存在變量提升
- 不能重復聲明
關於const:
- 創建塊級作用域
- 新建一個同名變量,不能重復賦值,但可以在新的作用域使用
關於var:
- 函數內部var的變量提升,聲明被提到函數最開頭
- 可能導致結果出錯,或者泄露變量
關於this關鍵字
- 直接被調用的函數,this為全局對象
- 被某個對象調用的函數,this為當前對象
關於閉包:
- 由於在 Javascript 語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解成 定義在一個函數內部的函數
- 閉包的用途:可以讀取函數內部的變量(作用域鏈),讓這些變量的值始終保持在內存中
- 注意,外層函數每次運行,都會生成一個新的閉包,而這個閉包又會保留外層函數的內部變量,所以內存消耗很大。因此不能濫用閉包,否則會造成網頁的性能問題。
ES6中的正則表達式
定義
- 直接量語法 /pattern/attributes
- 創建 RegExp 對象的語法: new RegExp(pattern, attributes);
- 參數 pattern 是一個字符串,指定了正則表達式的模式或其他正則表達式。
- 參數 attributes 是一個可選的字符串,包含屬性 "g"、"i" 和 "m",分別用於指定全局匹配、區分大小寫的匹配和多行匹配。ECMAScript 標准化之前,不支持 m 屬性。如果 pattern 是正則表達 式,而不是字符串,則必須省略該參數
用途
- 驗證表單:登錄注冊驗證
- 字符串操作:過濾,查找
ES6中的prototype與class
1.傳統的Javascript是動態語言,又可稱之為Prototype-based Language,JavaScript繼承方法是使用prototype,透過指定prototype屬性,便可以指定要繼承的目標。屬性可以在運行時添加到或從對象中刪除,引擎會為運行中的對象創建一個屬性字典,新的屬性都要透過字典查找屬性在內存中的位置。
-
原型鏈的原理: [[Prototype]] 機制是一種存在於一個對象上的內部鏈接,它指向一個其他對象。
-
當一個屬性/方法引用在一個對象上發生,而這樣的屬性/方法又不存在時,這個鏈接就會被使用。在這 種情況下,[[Prototype]] 鏈接告訴引擎去那個被鏈接的對象上尋找該屬性/方法。接下來,如果那個對 象也不能滿足查詢,就沿着它的 [[Prototype]] 查詢,如此繼續。這種對象間的一系列鏈接構成了所謂 的“原形鏈”。
-
好比一棟樓,頂樓是最高的原型,每層樓的__proto__都指向上一樓,可以簡稱這就是繼承。當你要查找 一個對象的屬性attr時。先在第一樓找(obj.attr)。如果找不到,跑到二樓找(obj.proto.attr)。二樓 找不到,就跑到三樓找,(obj.proto.proto.attr)。直到找到頂樓為止。
- 可以想到,如果一個屬性位於原型鏈的頂端,那么這個查找過程將會十分低效。所以如果重復查找原型 鏈頂端的屬性,通過臨時變量來緩存結果是個提高性能的不錯的方法。
關於原型及原型鏈
- prototype 原型
- 我們創建的每個函數都有一個 prototype(原型)屬性
- 使用原型的好處是可以讓所有對象實例共享它所包含的屬性和方法
- 換句話說,不必在構造函數中定義對象實例的信息,而是可以將這些信息直接添加到原型中
- 理解原型對象:
在默認情況下,所有原型對象都會自動獲得一個 constructor(構造函數)屬性,這個屬 性包含一個指向 prototype 屬性所在函數的指針 雖然可以通過對象實例訪問保存在原型中的值,但卻不能通過對象實例重寫原型中的值 - 原型的動態性:
由於在原型中查找值的過程是一次搜索,因此我們對原型對象所做的任何修改都能夠立 即從實例上反映出來,即使是先創建了實例后修改原型也照樣如此 實例中的指針僅指向原型,而不指向構造函數
- proto
- 當調用構造函數創建一個新實例后,該實例的內部將包含一個指針 proto,指向構造函數的原型
- 簡單來說,當我們訪問一個對象的屬性時,如果這個屬性不存在,那么就會去 proto 里找,這個 proto 又會有自己的 proto,於是就這樣一直找下去,直到找到為止
- 原型鏈
- JavaScript 中描述了原型鏈的概念,並將原型鏈作為實現繼承的主要方法
- 其基本思想是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法
- 每個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一
個指向原型對象的內部指針 - 假如我們讓原型對象等於另一個類型的實例,此時的原型對象將包含一個指向另一個原型的指針,相應地,另一個原型中也包含着一個指向另一個構造函數的指針
- 假如另一個原型又是另一個類型的實例,那么上述關系依然成立,如此層層遞進,就構成了實例與原型的鏈條
- 這就是所謂原型鏈的基本概念
箭頭函數
定義
- 箭頭函數使用類似於=>這樣的語法定義函數,
- 支持表達式模式和語句模式
數組的一些箭頭函數
作用域
- 箭頭函數:作用域最大特點在於和父作用域具有一樣的this。綁定定義時所在的作用域
- 普通函數:this 既不指向函數自身也不指向函數的詞法作用域,this 實際上是在函數被調用時發生 的綁定,它指向什么完全取決於函數在哪里被調用。
- 箭頭函數根本沒有自己的this,導致內部的this就是外層代碼塊的this
- setInterval() 方法可按照指定的周期(以毫秒計)來調用函數或計算表達式 5. setTimeout() 方法用於在指定的毫秒數后調用函數或計算表達式。
- 箭頭函數中,this的作用域在Timer內,由於閉包,保存了變量更新的值
- 普通函數的s2一直出於全局作用域,值沒有被保存,每次值都為0
Ajax介紹
- AJAX = Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。
- AJAX 不是新的編程語言,而是一種使用現有標准的新方法。
- AJAX 最大的優點是在不重新加載整個頁面的情況下,可以與服務器交換數據並更新部分網頁內容。
- AJAX 不需要任何瀏覽器插件,但需要用戶允許JavaScript在瀏覽器上執行。
- AJAX 是一種在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。
ES6的異步操作:認識promise和async
Promise
- 含義:
- Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和 更強大。它由社區最早提出和實現,ES6 將其寫進了語言標准,統一了用法,原生提供了 Promise對象。
- 所謂Promise,簡單說就是一個容器,里面保存着某個未來才會結束的事件(通常是一個異步 操作)的結果。從語法上說,Promise 是一個對象,從它可以獲取異步操作的消息。Promise 提供統一的 API,各種異步操作都可以用同樣的方法進行處理。
- 為異步編程提供了一種新的方式,Promise把未來將用到的值當做一等對象
- 給你一個諾言,要么成功(上天堂),要么失敗(下地獄)
- 特點:
- 對象的狀態不受外界影響。 Promise對象代表一個異步操作,有三種狀態:pending(進行中)、fulfilled(已成功)和 rejected(已失敗)。
- 只有異步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。
- 一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise對象的狀態改變,只有兩種可能:從pending變為fulfilled和從pending變為rejected。
- 只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果,這時就稱為 resolved(已定型)。
- 如果改變已經發生了,你再對Promise對象添加回調函數,也會立即得到這個結果。這與事件 (Event)完全不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的。
- 調用resolve或reject以后,Promise 的使命就完成了,后繼操作應該放到then方法里面,而 不應該直接寫在resolve或reject的后面
- 作用:對延時和異步操作流程進行控制
關於async
- 定義
- Async函數聲明async function foo() {}
- Async 函數表達式 const foo = async function () {};
- Async 定義對象的方法 let obj = { async foo() {} }
- Async 箭頭函數 const foo = async () => {};
2.返回promises
- 正常then,fulfilled
- 報錯catch,rejected
- 使用await異步得到結果和錯誤
學習module體系
- 模塊(module)體系,將一個大程序拆分成互相依賴的小文件,再用簡單的方法拼裝起來。
- ES6 模塊的設計思想是盡量的靜態化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變 量。
- ES6 模塊不是對象,而是通過export命令顯式指定輸出的代碼,再通過import命令輸入。
- 模塊功能主要由兩個命令構成:export和import。export命令用於規定模塊的對外接口 ,import命令用於輸入其他模塊提供的功能。
- 一個模塊就是一個獨立的文件。該文件內部的所有變量,外部無法獲取。如果你希望外部能夠讀取 模塊內部的某個變量,就必須使用export關鍵字輸出該變量。