ECMAScript
ECMAScript 是一種由Ecma國際 通過ECMA-262標(biāo)準化的腳本程序設(shè)計語言 。這種語言在萬維網(wǎng)上應(yīng)用廣泛,它往往被稱為JavaScript或JScript,所以它可以理解為是JavaScript的一個標(biāo)準,但實際上后兩者是ECMA-262標(biāo)準的實現(xiàn)和擴展。
LET 和 CONST
let變量
ES5 中作用域有全局作用域、函數(shù)作用域。沒有塊作用域的概念。
ES6 中新增了塊級作用域。塊作用域由 { } 包括,if語句和 for語句里面的{ }也屬于塊作用域。
let聲明的變量在let命令所在的代碼塊中有效。不存在變量提升,只能先聲明后使用。
如果區(qū)塊中存在let和const命令,這個區(qū)塊對這些命令聲明的變量,從一開始就形成了封閉作用域。
var a = 1;
{
a = 2; //ReferenceError
let a = 'a';
console.log(a); //'a';
}
在相同塊級作用域中,不能用let重復(fù)聲明同一變量。即使已存在的變量是通過var聲明的。
let a = 1; let a = 2; //報錯
let a = 1; var a = 2; //報錯,var聲明有變量提升作用
const常量
聲明常量必須馬上賦值且不能再改變。const和let有類似的特點:在塊級作用域內(nèi)有效,聲明不提升,存在暫存死區(qū),不可重復(fù)聲明。
const let 和 var的區(qū)別
var定義的變量,沒有塊的概念,可以跨塊訪問, 不能跨函數(shù)訪問。
let定義的變量,只能在塊作用域里訪問,不能跨塊訪問,也不能跨函數(shù)訪問。
const用來定義常量,使用時必須初始化(即必須賦值),只能在塊作用域里訪問,而且不能修改。
解構(gòu)賦值
從數(shù)組和對象中提取值,對變量進行賦值,稱為解構(gòu)賦值(destructuring)
數(shù)組解構(gòu)賦值
數(shù)組的解構(gòu)賦值,按照對應(yīng)順序賦值,如果值數(shù)量超出則多余的值被拋棄,如果值不夠則為undefined
let arr = [1, [2, 3]];
let [a, [b, c]] = arr;
console.log(a,b,c);
let arr = [, [2, 3]];
let [a='123', [b, c]] = arr;
console.log(a,b,c);
//ES5非解構(gòu)賦值的情況
let arr = [0,1,2];
let a = arr[0];
let b = arr[1];
let c = arr[2];
不完全解構(gòu)
let [a = 1, b] = []; // a = 1, b = undefined
剩余運算解構(gòu)
let [a, ...b] = [1, 2, 3];
//a = 1
//b = [2, 3]
解構(gòu)默認值
//當(dāng)要解構(gòu)的變量 為undefined時 取默認值 否則取解構(gòu)值
let [a = 2] = [undefined]; // a = 2
對象的解構(gòu)賦值
1.對象的解構(gòu)賦值和數(shù)組的解構(gòu)賦值其實類似,但是數(shù)組的數(shù)組成員是有序的
而對象的屬性則是無序的,所以對象的解構(gòu)賦值簡單理解是等號的左邊和右邊的結(jié)構(gòu)相同。
// 對象的解構(gòu)賦值是根據(jù)key值進行匹配
let { name:Name,age } = { name:'swr',age:28 }
console.log(Name) // 'swr'
console.log(age) // 28
字符串?dāng)U展方法
for...of方法
const exp= ['mini', 'mani', 'mo'];
for (const value of exp) {
console.log(value)
}
startsWidth() endsWidth() includes()。
let s = 'hello word!';
s.startsWith('hello'); //true
s.endsWidth('word'); //false
s.includes('o'); //true
includes和indexOf的區(qū)別:
1)includes可以判斷數(shù)組中有NaN indexOf不行
2)includes返回bool類型、indexOf返回數(shù)值
var ary = [NaN];
console.log(ary.indexOf(NaN))//-1
console.log(ary.includes(NaN))//true
at()
用于返回給定位置的字符,對于編碼大于0xFFFF的字符用at()方法。
//es5 charAt()方法 對于編碼大于0xFFFF字符無法解析
'ab'.charAt(0) //'a'
'??a'.charAt(0) //'\uD842'
'??a'.at(0) //'??'
repeat()
repeat 方法,就是對一個字符串重復(fù)多次,它接受一個參數(shù),重復(fù)的次數(shù),返回一個新字符串。
let msg = "Hello";
console.log(msg.repeat(4)) //HelloHelloHelloHello
模版字符串
用反引號【`】標(biāo)識,它可以當(dāng)作普通字符串使用,也可以用來定義多行字符串,或者在字符串中嵌入變量。
普通用法
let name = 'zq';
`your name is ${name}`;
模版字符串中空格和縮緊都會被保留,可以用trim()方法消除。
`<ul>
<li>123 <li>
</ul>`.trim();
如果在模板字符串中需要使用反引號,則前面需要用反斜杠轉(zhuǎn)義
let greeting = `\`Yo\` World!`; // `Yo` World!
數(shù)值相關(guān)擴展方法
新增三角函數(shù)
Math.sinh(x) //返回x的雙曲正弦
Math.cosh(x) //返回x的雙曲余弦
Math.tanh(x) //返回x的雙曲正切
Math.asinh(x) //返回x的反雙曲正弦
Math.acosh(x) //返回x的反雙曲余弦
Math.atanh(x) //返回x的反雙曲正切
ES6新增了指數(shù)運算符**
let a = 2;
a = a**3; //8
//可以簡寫成 a **= 3
a = Math.pow(a,3);//傳統(tǒng)寫法
函數(shù)的擴展
函數(shù)參數(shù)可設(shè)置默認值
function (x = 1) {}
function (x, x=1) {} //報錯
函數(shù)參數(shù)是默認聲明的,不能用let或const再次聲明,可以用var再次聲明]
function (x) {
let x = 1; //報錯
var x = 1; //正常
}
拓展運算符
ES6 引入 拓展運算符(形式為【... +變量名】),用于獲取函數(shù)的多余參數(shù)。
function show(...a){
console.log(a); // [14, 12, 54, 33, 22]
}
show(14,12,54,33,22);
擴展運算符可以簡寫數(shù)組拼接。
// 以往拼接數(shù)組的方式
let arr1 = [1,2,3]
let arr2 = [4,5,6]
let arr3 = arr1.concat(arr2)
console.log(arr3) // [ 1, 2, 3, 4, 5, 6 ]
// 擴展運算符拼接方式
let arr1 = [1,2,3]
let arr2 = [4,5,6]
let arr3 = [...arr1,...arr2]
console.log(arr3) // [ 1, 2, 3, 4, 5, 6 ]
拓展運算符解決數(shù)組引用復(fù)制問題。
let a = [14,12,54,33,22];
let b = a; // 相當(dāng)于copy
a.push(44);
console.log(a); // [14, 12, 54, 33, 22, 44]
console.log(b); // [14, 12, 54, 33, 22, 44]
let a = [14,12,54,33,22];
let b = [...a];
a.push(44);
console.log(a); // [14, 12, 54, 33, 22, 44]
console.log(b); // [14, 12, 54, 33, 22]
name屬性
函數(shù)的name屬性,返回該函數(shù)的函數(shù)名。如果將一個匿名函數(shù)賦值給一個變量,ES5 的name屬性,會返回空字符串,而 ES6 的name屬性會返回實際的函數(shù)名。
let fn = () => {
let fn1 = function (){}
//es5
fn1.name //''
//es6
fn.name //'fn'
箭頭函數(shù)
箭頭函數(shù)是ES6之后較之前函數(shù)更為簡潔的一種函數(shù)書寫方式
箭頭函數(shù)不綁定this,導(dǎo)致內(nèi)部的this就是指向外層代碼塊的this
var a = 20;var obj = {
a: 10,
b: () => {
console.log(this.a); //undefined
console.log(this); //window
},
c: function() {
console.log(this.a); //10
console.log(this); //obj{...}
}
}
obj.b();
obj.c();
箭頭函數(shù)的書寫
使用 var、let、const 定義function
參數(shù)2-1. 沒有參數(shù):需要寫小括號 ' ( ) '占位2-2. 一個參數(shù):可以不加小括號直接寫2-3. 多個參數(shù):參數(shù)寫在小括號 ' ( ) ' 里,用逗號隔開
箭頭 ' => '
函數(shù)體寫在箭頭后面4-1. 一條語句:可以不加花括號直接寫4-2. 多條語句:將語句放入花括號中' { } '
//ES5
var fn1 = function(){
console.log('fn1')
}
//ES6
var fn1 = (res)=>{
console.log(res)
}
//執(zhí)行函數(shù)
fn1() // -> fn1
Module模塊
ES6 模塊通過export命令顯式指定輸出的代碼,再通過import命令輸入。使用模塊自動采用嚴格模式
export
export 用于規(guī)定模塊的對外接口,輸出變量,函數(shù),類。
//寫法1
export let a = 1;
export function b () {};
//寫法2
let a = 1;
function b () {};
export {a, b};
//報錯
let a = 1;
export a;
通常輸出的變量就是本來的名字,可以用 as 修改。
function a () {};
let b = 1;
export {
a as fnA,
b as vB
};
export輸出的接口和模塊內(nèi)部的變量是動態(tài)綁定關(guān)系,變量值改變,通過接口獲取的值也相應(yīng)改變。
//test.js
export let a = 1;
setTimeout(() => a=2, 1000);
import {a} from './test'
//a = 1, 1s后變成2
export必須處于模塊頂層,如果處于塊級作用域會報錯。import也是如此。
function () {
export let a = 1; //報錯
}
import
使用import加載模塊
import {a, b} from './test'
import后跟一個大括號,括號內(nèi)指定需要導(dǎo)入的變量,變量名需對應(yīng)。但可以通過as修改。
import {a as vA, b as vB} from './test';
import后的from用來指定模塊的路徑,絕對路徑或相對路徑,.js可以省略。如果模塊有配置文件,則不帶路徑。
import有提升效果,會提升到模塊頭部,先執(zhí)行。
由于import是靜態(tài)執(zhí)行,不能使用表達式和變量。比如from后的路徑不能用一個變量代替。
import會執(zhí)行所加載的模塊,可以直接跟模塊名。但多次加載相同模塊只執(zhí)行一次,import語句是單例模式。
import 'module_name';
import {a} from './test';
import from './test';
//等同于
import {a,b} from './test';