ECMAScript簡稱就是ES,你可以把它看成是一套標準,JavaScript就是實施了這套標準的一門語言 現(xiàn)在主流瀏覽器使用的是ECMAScript5
1. 作用域變量
作用域就是一個變量的作用范圍缤至。也就是你聲明一個變量以后,這個變量可以在什么場合下使用 以前的JavaScript只有全局作用域,還有一個函數(shù)作用域
1.1 var的問題
var沒有塊級作用域,定義后在當前閉包中都可以訪問熟史,如果變量名重復籽慢,就會覆蓋前面定義的變量痕届,并且也有可能被其他人更改瞳抓。
if(true) {vara ="a";// 期望a是某一個值}console.log(a);
var在for循環(huán)標記變量共享倘感,一般在循環(huán)中使用的i會被共享置谦,其本質(zhì)上也是由于沒有塊級作用域造成的
for(vari =0; i <3; i++) {? ? setTimeout(function(){? ? ? ? alert(i);? ? },0); }
結(jié)果
彈窗三次?3
1.2 塊級作用域
在用var定義變量的時候堂鲤,變量是通過閉包進行隔離的,現(xiàn)在用了let媒峡,不僅僅可以通過閉包隔離瘟栖,還增加了一些塊級作用域隔離。 塊級作用用一組大括號定義一個塊,使用 let 定義的變量在大括號的外面是訪問不到的
1.2.1 實現(xiàn)塊級作用域
if(true){letname ='zfpx';}console.log(name);// ReferenceError: name is not defined
1.2.2 不會污染全局對象
if(true){letname ='zfpx';}console.log(window.name);
結(jié)果 undefined
1.2.3 for循環(huán)中也可以使用i
// 嵌套循環(huán)不會相互影響for(leti =0; i <3; i++) {console.log("out", i);for(leti =0; i <2; i++) {console.log("in", i);? ? ? ? }? ? }
結(jié)果 out 0 in 0 in 1 out 1 in 0 in 1 out 2 in 0 in 1
1.2.4 重復定義會報錯
if(true){leta =1;leta =2;//Identifier 'a' has already been declared}
1.2.5 不存在變量的預解釋
for(leti =0; i <2; i ++){console.log('inner',i);leti =100;}
結(jié)果?i is not defined
1.2.6 閉包的新寫法
以前
;(function(){})();
現(xiàn)在
{
}
2. 常量
使用const我們可以去聲明一個常量谅阿,常量一旦賦值就不能再修改了
2.1 常量不能重新賦值
constMY_NAME ='zfpx';MY_NAME ='zfpx2';//Assignment to constant variable
2.2 變量值可改變
注意const限制的是不能給變量重新賦值半哟,而變量的值本身是可以改變的,下面的操作是可以的
constnames = ['zfpx1'];names.push('zfpx2');console.log(names);
2.3 不同的塊級作用域可以多次定義
constA ="0";{constA ="A";console.log(A)}{constA ="B";console.log(A)}console.log(A)
結(jié)果 A B 0
3. 解構(gòu)
3.1 解析數(shù)組
解構(gòu)意思就是分解一個東西的結(jié)構(gòu),可以用一種類似數(shù)組的方式定義N個變量,可以將一個數(shù)組中的值按照規(guī)則賦值過去签餐。
var[name,age] = ['zfpx',8];console.log(name,age);
3.2 嵌套賦值
let[x, [y], z] = [1, [2.1,2.2]];console.log(x, y, z);let[x, [y,z]] = [1, [2.1,2.2]];console.log(x,y,z);
這樣數(shù)組里的第一個項目就會交給前面name這個變量寓涨,第二個項目的值會分配給age這個變量
3.3 省略賦值
let[, , x] = [1,2,3];console.log(x);
3.2 解構(gòu)對象
對象也可以被解構(gòu)
varobj = {name:'zfpx',age:8};//對象里的name屬性的值會交給name這個變量,age的值會交給age這個變量var{name,age} = obj;//對象里的name屬性的值會交給myname這個變量氯檐,age的值會交給myage這個變量let{name: myname, age: myage} = obj;console.log(name,age,myname,myage);
3.3 默認值
在賦值和傳參的時候可以使用默認值
let[a ="a", b ="b", c =newError('C必須指定')] = [1, ,3];console.log(a, b, c);functionajax(options){varmethod = options.method ||"get";vardata = options.data || {};//.....}functionajax({method = "get", data}){console.log(arguments);}ajax({? ? method:"post",? ? data: {"name":"zfpx"}});
4. 字符串
4.1 模板字符串
模板字符串用反引號(數(shù)字1左邊的那個鍵)包含戒良,其中的變量用${}括起來
varname ='zfpx',age =8;letdesc =`${name}is${age}old!`;console.log(desc);//所有模板字符串的空格和換行,都是被保留的varstr =`<ul>
<li>a</li>
<li>b</li>
</ul>`;console.log(str);
其中的變量會用變量的值替換掉
4.2 帶標簽的模板字符串
可以在模板字符串的前面添加一個標簽男摧,這個標簽可以去處理模板字符串 標簽其實就是一個函數(shù),函數(shù)可以接收兩個參數(shù),一個是strings,就是模板字符串里的每個部分的字符 還有一個參數(shù)可以使用rest的形式values,這個參數(shù)里面是模板字符串里的值
varname ='zfpx',age =8;functiondesc(strings,...values){console.log(strings,values);}desc`${name}is${age}old!`;
4.3 字符串新方法
includes():返回布爾值蔬墩,表示是否找到了參數(shù)字符串译打。
startsWith():返回布爾值,表示參數(shù)字符串是否在源字符串的頭部拇颅。
endsWith():返回布爾值奏司,表示參數(shù)字符串是否在源字符串的尾部。
vars ='zfpx';s.startsWith('z')// trues.endsWith('x')// trues.includes('p')// true
第二個參數(shù)樟插,表示開始搜索的位置
vars ='zfpx';console.log(s.startsWith('p',2));// trueconsole.log(s.endsWith('f',2));// trueconsole.log(s.includes('f',2));// false
endsWith的行為與其他兩個方法有所不同韵洋。它針對前n個字符,而其他兩個方法針對從第n個位置直到字符串結(jié)束
4.4 repeat
repeat方法返回一個新字符串黄锤,表示將原字符串重復n次搪缨。
'x'.repeat(3);'x'.repeat(0);
5. 函數(shù)
5.1 默認參數(shù)
可以給定義的函數(shù)接收的參數(shù)設置默認的值 在執(zhí)行這個函數(shù)的時候,如果不指定函數(shù)的參數(shù)的值鸵熟,就會使用參數(shù)的這些默認的值
letdesc? =function(name='zfpx',age=8){console.log(`${name}is${age}years old!`);}desc('zfpx2');
5.1 展開操作符
把...放在數(shù)組前面可以把一個數(shù)組進行展開,可以把一個數(shù)組直接傳入一個函數(shù)而不需要使用apply
//傳入?yún)?shù)letprint =function(a,b,c){console.log(a,b,c);}print([1,2,3]);print(...[1,2,3]);// 可以替代applyvarm1 =Math.max.apply(null, [8,9,4,1]);varm2 =Math.max(...[8,9,4,1]);// 可以替代concatvararr1 = [1,3];vararr2 = [3,5];vararr3 = arr1.concat(arr2);vararr4 = [...arr1, ...arr2];console.log(arr3,arr4);//類數(shù)組的轉(zhuǎn)數(shù)組functionmax(a,b,c){console.log(Math.max(...arguments));}max(1,3,4);
5.2 剩余操作符
剩余操作符可以把其余的參數(shù)的值都放到一個叫b的數(shù)組里面
letrest =function(a,...b){console.log(a,b);}rest(1,2,3);
5.3 解構(gòu)參數(shù)
letdestruct =function({name,age}){console.log(name,age);}destruct({name:'zfpx',age:6});
5.4 函數(shù)的名字
ECMAScript 6 給函數(shù)添加了一個name屬性
vardesc =functiondescname(){}console.log(desc.name);
5.5 箭頭函數(shù)
箭頭函數(shù)簡化了函數(shù)的的定義方式副编,一般以 "=>" 操作符左邊為輸入的參數(shù),而右邊則是進行的操作以及返回的值inputs=>output
[1,2,3].forEach(val =>console.log(val)););
輸入?yún)?shù)如果多于一個要用()包起來流强,函數(shù)體如果有多條語句需要用{}包起來
箭頭函數(shù)根本沒有自己的this痹届,導致內(nèi)部的this就是外層代碼塊的this。 正是因為它沒有this打月,從而避免了this指向的問題队腐。
var person = {? ? name:'zfpx',? ? getName:function(){-? ? ? ? setTimeout(function(){console.log(this);},1000); //在瀏覽器執(zhí)行的話this指向window+? ? ? ? setTimeout(() => console.log(this),1000);//在瀏覽器執(zhí)行的話this指向person}}person.getName();
5.6 數(shù)組的新方法
5.6.1 from
將一個數(shù)組或者類數(shù)組變成數(shù)組,會復制一份
letnewArr =Array.from(oldArr);
5.6.2 Array.of
of是為了將一組數(shù)值,轉(zhuǎn)換為數(shù)組
console.log(Array(3,4),Array(3,4).length,Array.of(3,4),Array.of(3,4).length);
5.6.3 copyWithin
Array.prototype.copyWithin(target, start = 0, end = this.length) 蓋目標的下標 開始的下標 結(jié)束的后一個的下標
[1,2,3,4,5].copyWithin(0,1,2);
5.6.4 find
查到對應的元素和索引
let arr = [1, 2 ,3, 3, 4, 5];
? ? let find = arr.find((item, index, arr) => {
? ? ? ? return item === 3;
? ? });
? ? let findIndex = arr.findIndex((item, index, arr) => {
? ? ? ? return item === 3;
? ? });
? ? console.log(find, findIndex);
5.6.5 fill
就是填充數(shù)組的意思 會更改原數(shù)組 Array.prototype.fill(value, start, end = this.length);
let arr = [1, 2, 3, 4, 5, 6];
arr.fill('a', 1, 2);
console.log(arr);
6. 對象
6.1 對象字面量
如果你想在對象里添加跟變量名一樣的屬性,并且屬性的值就是變量表示的值就可以直接在對象里加上這些屬性
letname ='zfpx';letage =8;letgetName =function(){console.log(this.name);}letperson = {? ? name,? ? age,? ? getName}person.getName();
6.2 Object.is
對比兩個值是否相等
console.log(Object.is(NaN,NaN));
6.3 Object.assign
把多個對象的屬性復制到一個對象中,第一個參數(shù)是復制的對象,從第二個參數(shù)開始往后,都是復制的源對象
varnameObj = {name:'zfpx'};varageObj = {age:8};varobj = {};Object.assign(obj,nameObj,ageObj);console.log(obj);//克隆對象functionclone(obj){returnObject.assign({}, obj);}
6.4 Object.setPrototypeOf
將一個指定的對象的原型設置為另一個對象或者null
varobj1? = {name:'zfpx1'};varobj2 =? {name:'zfpx2'};varobj = {};Object.setPrototypeOf(obj,obj1);console.log(obj.name);console.log(Object.getPrototypeOf(obj));Object.setPrototypeOf(obj,obj2);console.log(obj.name);console.log(Object.getPrototypeOf(obj));
6.5 proto
直接在對象表達式中設置prototype
varobj1? = {name:'zfpx1'};varobj3 = {? ? __proto__:obj1}console.log(obj3.name);console.log(Object.getPrototypeOf(obj3));
6.6 super
通過super可以調(diào)用prototype上的屬性或方法
letperson ={? ? eat(){return'milk';? ? }}letstudent = {? ? __proto__:person,? ? eat(){returnsuper.eat()+' bread'}}console.log(student.eat());
7. Symbol
ES6引入了一種新的原始數(shù)據(jù)類型Symbol奏篙,表示獨一無二的值 它是JavaScript語言的第七種數(shù)據(jù)類型
7.1 生成Symbol
Symbol值通過Symbol函數(shù)生成
lets =Symbol('zfpx');console.log(s);
7.2 作為屬性名
由于每一個Symbol值都是不相等的柴淘,這意味著Symbol值可以作為標識符,用于對象的屬性名秘通,就能保證不會出現(xiàn)同名的屬性
varluckNum =Symbol();varperson = {};person[luckNum] ='9';console.log(person[luckNum] );// 9在對象的內(nèi)部为严,使用Symbol值定義屬性時,Symbol值必須放在方括號之中varperson = {[luckNum]:'8'};
7.3 消除魔術(shù)變量
var Operator = {
? ? add: Symbol()
};
function calculate(op, a, b) {
? ? switch (op) {
? ? ? ? case Operator.add:
? ? ? ? ? ? return a + b;
? ? ? ? ? ? break;
? ? ? ? case Operator.minus:
? ? ? ? ? ? return a - b;
? ? ? ? ? ? break;
? ? }
}
console.log(calculate(Operator.add, 10,10));
console.log(calculate(Operator.minus, 10,10));
8.生成器(Generator)與迭代器(Iterator)
Generator是一個特殊的函數(shù)充易,執(zhí)行它會返回一個Iterator對象梗脾。 通過遍歷迭代器,Generator函數(shù)運行后會返回一個遍歷器對象盹靴,而不是普通函數(shù)的返回值炸茧。
8.1 Iterators
迭代器有一個next方法,每次執(zhí)行的時候會返回一個對象 對象里面有兩個屬性稿静,一個是value表示返回的值嘱能,還有就是布爾值done,表示是否迭代完成
functionbuy(books){leti =0;return{? ? ? ? next(){letdone = i == books.length;letvalue = !done ? books[i++] :undefined;return{? ? ? ? ? ? ? ? value: value,? ? ? ? ? ? ? ? done: done? ? ? ? ? ? }? ? ? ? }? ? }}letiterators = buy(['js','html']);varcurr;do{? ? curr = iterators.next();console.log(curr);}while(!curr.done);
8.2 Generators
生成器用于創(chuàng)建迭代器
function*buy(books){for(vari=0;i
8.3 連續(xù)執(zhí)行
varfs =require('fs');functiondouble(val){returnfunction(next){? ? ? ? setTimeout(function(){? ? ? ? ? ? next(val*val);? ? ? ? },1000);? ? }}co(function*(){vara =yielddouble(2);console.log(a);varb =yielddouble(3);console.log(b);})();functionco(fn){returnfunction(){varit = fn();//得到迭代器varcurr =null;//當前對象functionnext(val){? ? ? ? ? ? curr = it.next(val);if(!curr.done){? ? ? ? ? ? ? ? curr.value(next);? ? ? ? ? ? }? ? ? ? }? ? ? ? next();? ? }}
8.4 promise連續(xù)運行
function*genFunc(initValue){letfirst =yieldnewPromise((resolve) => {? ? ? ? setTimeout(()=>{? ? ? ? ? ? resolve(initValue+'-first');? ? ? ? },1000);? ? });letsecond =yieldnewPromise((resolve) => {? ? ? ? setTimeout(()=>{? ? ? ? ? ? resolve(first+'-second');? ? ? ? },1000);? ? });letthird =yieldnewPromise((resolve) => {? ? ? ? setTimeout(()=>{? ? ? ? ? ? resolve(second+'-third');? ? ? ? },1000);? ? });}varit = genFunc('init');it.next().value.then((value)=> {console.log(value);returnit.next(value).value;}).then((value)=> {console.log(value);returnit.next(value).value;}).then((value)=> {console.log(value);returnit.next(value).value;})
8.5 co
co用于自動執(zhí)行迭代器
function*genFunc(initVal){letfirst =yieldnewPromise((resolve) => {? ? ? ? setTimeout(()=>{? ? ? ? ? ? resolve('first');? ? ? ? },1000);? ? });letsecond =yieldnewPromise((resolve) => {? ? ? ? setTimeout(()=>{? ? ? ? ? ? resolve(first+'-second');? ? ? ? },1000);? ? });letthird =yieldnewPromise((resolve) => {? ? ? ? setTimeout(()=>{? ? ? ? ? ? resolve(second+'-third');? ? ? ? },1000);? ? });}functionco(fn){returnfunction(initVal){varit = fn();//得到迭代器varcurr =null;//當前迭代到的對象functionnext(val){? ? ? ? ? ? curr = it.next(val);console.log(val);if(!curr.done){? ? ? ? ? ? ? ? curr.value.then(next)? ? ? ? ? ? }? ? ? ? }? ? ? ? next(initVal);? ? }}co(genFunc)();/*
var it = genFunc('init');
it.next().value.then((value)=> {
? ? console.log(value);
? ? return it.next(value).value;
}).then((value)=> {
? ? console.log(value);
? ? return it.next(value).value;
}).then((value)=> {
? ? console.log(value);
? ? return it.next(value).value;
})
*/
9. 類
9.1 class
使用class這個關鍵詞定義一個類,基于這個類創(chuàng)建實例以后會自動執(zhí)行constructor方法,此方法可以用來初始化
classPerson{? ? constructor(name){this.name = name;? ? }? ? getName(){console.log(this.name);? ? }}letperson =newPerson('zfpx');person.getName();
9.2 get與set
getter可以用來得獲取屬性擒贸,setter可以去設置屬性
classPerson{? ? constructor(){this.hobbies = [];? ? }? ? set hobby(hobby){this.hobbies.push(hobby);? ? }? ? get hobby(){returnthis.hobbies;? ? }}letperson =newPerson();person.hobby ='basketball';person.hobby ='football';console.log(person.hobby);
9.3 靜態(tài)方法-static
在類里面添加靜態(tài)的方法可以使用static這個關鍵詞,靜態(tài)方法就是不需要實例化類就能使用的方法
classPerson{? static add(a,b){returna+b;? }}console.log(Person.add(1,2));
9.4 繼承extends
一個類可以去繼承其它的類里的東西
classPerson{? constructor(name){this.name = name;? }}classTeacherextendsPerson{? ? constructor(name,age){super(name);this.age = age;? ? }}varteacher =newTeacher('zfpx',8);console.log(teacher.name,teacher.age);
10.集合
10.1 Set
一個Set是一堆東西的集合,Set有點像數(shù)組,不過跟數(shù)組不一樣的是,Set里面不能有重復的內(nèi)容
varbooks =newSet();books.add('js');books.add('js');//添加重復元素集合的元素個數(shù)不會改變books.add('html');books.forEach(function(book){//循環(huán)集合console.log(book);})console.log(books.size);//集合中元數(shù)的個數(shù)console.log(books.has('js'));//判斷集合中是否有此元素books.delete('js');//從集合中刪除此元素console.log(books.size);console.log(books.has('js'));books.clear();//清空 setconsole.log(books.size);
10.2 Map
可以使用 Map 來組織這種名值對的數(shù)據(jù)
varbooks =newMap();books.set('js',{name:'js'});//向map中添加元素books.set('html',{name:'html'});console.log(books.size);//查看集合中的元素console.log(books.get('js'));//通過key獲取值books.delete('js');//執(zhí)照key刪除元素console.log(books.has('js'));//判斷map中有沒有keybooks.forEach((value, key) => {//forEach可以迭代mapconsole.log( key +' = '+ value);});books.clear();//清空map
11.模塊
可以根據(jù)應用的需求把代碼分成不同的模塊 每個模塊里可以導出它需要讓其它模塊使用的東西 在其它模塊里面可以導入這些模塊導出的東西
11.1 模塊
在瀏覽器中使用模塊需要借助 導出
exportvarname ='zfpx';exportvarage =8;
導入
//import {name,age} from './school.js';import*asschoolfrom'./school.js';console.log(school.name,school.age);
在頁面中引用
11.2 重命名
導出時重命名
functionsay(){console.log('say');}export{sayassay2};
導入時重命名
import{say2assay3}from'./school.js';
11.3 默認導出
每個模塊都可以有一個默認要導出的東西 導出
exportdefaultfunctionsay(){console.log('say');}
導入
importsayfrom'./school.js';