ES6新特性

来源:https://www.cnblogs.com/ruhaoren/archive/2019/09/25/11575179.html
-Advertisement-
Play Games

從ES6開始,JavaScript就朝著工程化和麵向對象的大步邁進,我們並不知道這對於年輕的JavaScript來說是好還是壞,因為它最開始是做為一款輕量級的腳本語言而風靡全球的。這個問題就留給時間來證明吧! ...


ECMAScript 6 是ECMA於2015.06發佈的版本,作為一個分界點,現在我們通常把這之後的版本統稱為ES6。ES6帶來了許多全新的語法,同時添加了類的概念,可以預見的是,JavaScript正朝著工程化語言邁進,我們並不知道這對於年輕的JavaScript來說是好還是壞,因為它最開始是做為一款輕量級的腳本語言而風靡全球的。

 

一  新的原始類型和變數申明

  1,symbol

  在ES6之前,我們知道JavaScript支持6種數據類型:object,string,boolean,number,null,undefined。現在,ES6新增了一種原始數據類型:symbol,表示獨一無二的值,即每個symbol類型的值都不相同。這讓我想起了另一個特殊的值:NaN,想一想,他們是不是有一點類似呢!

1 var sy = Symbol('test');
2 var sy1 = Symbol('test');
3 console.log(tepeof sy);//'symbol'
4 sy == sy1;//false
5 var sy2 = new Symbol('test');//error : Symbol is not a constructor

  創建symbol數據類型的值時,需要給Symbol函數傳遞一個字元串,並且有一點特殊的是:不能使用new關鍵字調用它。另外,每個symbol類型值都是獨一無二的,即使傳遞的是相同的字元串。

  2,let和const

  ES6新增了兩個申明變數的關鍵字:let和const。他們申明的變數僅在let和const關鍵字所在的代碼塊內起作用,即在使用let和const的那一對大括弧{}內起作用,也稱塊級作用域(ES6之前只有函數作用域和全局作用域)。let和const申明變數不會在預編譯過程中有提升行為(在全局申明也不會變成window的屬性),且不能重覆申明。所以要使用這類變數,只能在let和const關鍵字之後使用它們。

1 {
2     let a = 0;
3     console.log(a);//0
4 }
5 console.log(a);//error a is not defined

  const用來申明一個常量,申明時必須賦值,且一旦申明就不能改變。

  其實說const變數不能更改是不准確的,請看下麵的例子:

1 const obj = {
2     name:'ren',
3     age:12
4 };
5 obj = {};//error
6 obj.sex = male;
7 consol.log(obj);//{name:'ren',age:12;sex:'male'}

  const申明的如果是一個原始值,那麼上面的說法是準確的,如果const申明的是一個引用值,那麼更準確的說法應該是一個不能被重新賦值的變數。

  3,解構賦值 

  解構賦值是對賦值運算符的擴展。它是一種針對數組或者對象進行模式匹配,然後對其中的變數進行賦值。

let [a,b,c] = [1,2,3];
console.log(a,b,c);//1,2,3
**************************
let [a,b,c] = [1,,3];
console.log(a,b,c);//1,undefined,3
**************************
let [a,,b] = [1,2,3];
console.log(a,b);//1,3
**************************
let [a,..b] = [1,2,3];//...是剩餘運算符,表示賦值運算符右邊除第一個值外剩餘的都賦值給b
console.log(a,b);//1,[2,3]

  事實上所有可枚舉(iterable)的對象都可以使用結構賦值,例如數組,字元串對象,以及ES6新增的Map和Set類型。

1 let arr = 'hello';
2 let [a,b,c,d,e] = arr;
3 console.log(a,b,c,d,e);//'h','e','l','l','o'

  對象的解構賦值和數組類似,不過左邊的變數名需要使用對象的屬性名,並且用大括弧{}而非中括弧[]:

1 let obj = {name:'ren',age:12,sex:'male'};
2 let {name,age,sex} = obj;
3 console.log(name,age,sex);//'ren',12,'male';

   

二  新的對象和方法

  1,Map和Set

  Map對象用於保存鍵值對,任何值JavaScript支持的值都可以作為一個鍵或者一個值。這聽起來和對象差不多啊?其實它們還是有區別的:

    a) object的鍵只能是字元串或ES6的symbol值,而Map可以是任何值。

    b) Map對象有一個size屬性,存儲了鍵值對的個數,而object對象沒有類似屬性。

1 let myMap = new Map([['name','ren'],['age',12]]);
2 console.log(myMap);//{'name'=>'ren','age'=>12}
3 myMap.set('sex','male');
4 console.log(myMap);//{'name'=>'ren','age'=>12,'sex'=>'male'}
5 myMap.get('name');//'ren'
6 myMap.has('age');//true
7 myMap.delete('age');//true
8 myMap.has('age');//false
9 myMap.get('age');//undefined

  Map構造函數接收一個二維數組來創建一個Map對象。數組元素的第0位表示Map對象的key,第1位表示Map對象的value。

  Map對象使用set方法來新增數據,set方法接收兩個參數,第一個表示key,第二個表示value。使用get方法獲取數據,參數是對象的key。

  Map對象使用delete方法來刪除數據,接收一個參數,表示需要被刪除的key。

  Map對象使用has方法檢測是否已經具有某個屬性,返回boolean值。

  Set對象和Map對象類似,但它是用來存儲一組唯一值的,而不是鍵值對。類似數組,但它的每個元素都是唯一的。

1 let mySet = new Set([1,2,3]);
2 console.log(mySet);//{1,2,3}
3 mySet.add(4);
4 console.log(mySet);//{1,2,3,4}
5 mySet.delete(1);//true
6 mySet.has(1);//false

  利用Set對象唯一性的特點,可以輕鬆實現數組的去重:

1 let arr = [1,1,2,3,4,4];
2 let mySet = new Set(arr);
3 let newArr = Array.from(mySet);
4 console.log(newArr);//[1,2,3,4]

  2,對象新特性

  創建對象的字面量方式可以更加簡潔。直接使用變數名作為屬性,函數體作為方法,最終變數值變成屬性值,函數名變成方法名。

 1 let name = 'ren';
 2 let age = 12;
 3 let myself = {
 4     name,
 5     age,
 6     say(){
 7         console.log(this.name);
 8     }
 9 };
10 console.log(myself);//{name:'ren',age:12,say:fn}
11 myself.say();//'ren'

  對象的拓展運算符(...)三點。用於拷貝目標對象所有可遍歷的屬性到當前對象。

1 let obj = {name:'ren',age:12};
2 let person = {...obj};
3 console.log(person);//{name:'ren',age:12}
4 obj == person;//false
5 let another = {sex:'male'};
6 let someone = {...person,...another};//合併對象
7 console.log(someone);//{name:'ren',age:12,sex:'male'}

  ES6對象新增了兩個方法,assign和is。

  assign用於淺拷貝源對象可枚舉屬性到目標對象。

1 let source = {a:{ b: 1},b: 2};
2 let target = {c: 3};
3 Object.assign(target, source);
4 console.log(target);//{c: 3, a: {b:1}, b: 2}
5 source.a.b = 2;
6 console.log(target.a.b);//2

  如果有同名屬性,那麼目標對象的屬性值會被源對象的屬性值覆蓋。所以數組的表現就有一點特別了:

1 Object.assign([1,2,3],[11,22,33,44]);//[11,22,33,44]

  數組的index就是屬性名,當使用assign方法時,從第0位開始,目標數組的值便開始被源數組的值覆蓋了。

  is方法和(===)功能基本類似,用於判斷兩個值是否絕對相等。

1 Object.is(1,1);//true
2 Object.is(1,true);//false
3 Object.is([],[]);//false
4 Object.is(+0,-0);//false
5 Object.is(NaN,NaN);//true

  他們僅有的兩點區別是,is方法可以區分+0還是-0,還有就是它認為NaN是相等的。

  3,字元串新方法

  includes()判斷字元串是否包含參數字元串,返回boolean值。如果想要知道參數字元串出現的位置,還是需要indexOf或lastIndexOf方法。

  startsWith()/endsWith(),判斷字元串是否以參數字元串開頭或結尾。返回boolean值。這兩個方法可以有第二個參數,一個數字,表示開始查找的位置。

1 let str = 'blue,red,orange,white';
2 str.includes('blue');//true
3 str.startsWith('blue');//true
4 str.endsWith('blue');//false

  repeat()方法按指定次數返回一個新的字元串。如果次數是大於0的小數則向下取整,0到-1之間的小數則向上取整,其他負數將拋出錯誤。

1 console.log('hello'.repeat(2));//'hellohello'
2 console.log('hello'.repeat(1.9));//'hello'
3 console.log('hello'.repeat(-0.9));//''
4 console.log('hello'.repeat(-1.9));//error

  padStart()/padEnd(),用參數字元串按給定長度從前面或後面補全字元串,返回新字元串。

1 let arr = 'hell';
2 console.log(arr.padEnd(5,'o'));//'hello'
3 console.log(arr.padEnd(6,'o'));//'helloo'
4 console.log(arr.padEnd(6));//'hell  ',如果沒有指定將用空格代替
5 console.log(arr.padStart(5,'o'));//'ohell'

  另外,如果字元串加上補全的字元串超出了給定的長度,那麼,超出的部分將被截去。

  4,數組的新方法

  of()是ES6新增的用於創建數組的方法。of把傳入的參數當做數組元素,形成新的數組。

1 let arr = Array.of(1,'2',[3],{});
2 console.log(arr);//[1,'2',[3],{}]

  from()方法可以將可迭代對象轉換為新的數組。函數可接受3個參數:第一個表示將被轉換的可迭代對象,第二個是回調函數,將對每個數組元素應用該回調函數,然後返回新的值到新數組,第三個是回到函數內this的指向。後兩個參數是可選的。

1 let obj = {
2     double(n) {
3         return n * 2;
4     }
5 }
6 let arr = [1, 2, 3];
7 console.log(Array.from(arr, function (n){
8     return this.double(n);
9 }, obj)); // [2, 4, 6]

  find()和findIndex(),查找數組中符合條件的元素值或索引。如果有多個符合條件的,將只返回第一個。

1 let arr = [1,2,3,4,5];
2 console.log(arr.find(1));//1
3 console.log(arr.findIndex(5));//4

  fill()/copyWithin(),替換數組中部分元素,會修改原數組。

1 let arr = [1,2,3,4,5];
2 console.log(arr.fill(0,0,3));//[0,0,0,4,5]
3 //參數1表示目標值,參數2,3表示替換的始末位置,左閉右開區間。
4 console.log(arr.copyWithin(0,2,4));//[0,4,0,4,5]
5 //參數1表示修改的起始位置,參數2,3表示用來替換的數據的始末位置,左閉右開區間。

  fill()用指定的值替換,copyWithin()使用數組中原有的某一部分值替換。

  includes()用於檢測數組是否包含某個值,可以指定開始位置。

1 let arr = [1,2,3,4,5];
2 console.log(arr.includes(2));//true
3 console.log(arr.includes(1,1));//false

  

三  函數

  1,參數預設值

  ES6首次添加了參數預設值。我們再也不用在函數內部編寫容錯代碼了。

1 function add(a=1,b=2){
2     return a + b;
3 }
4 add();//3
5 add(2);//4
6 add(3,4);//7

  和參數預設值一起,ES6還帶來了不定參。它的功能和使用arguments差不多。

1 function add(...num){
2     return num.reduce(function(result,value){
3         return result + value;
4     });
5 }
6 add(1,2,3,4);//10

  下麵介紹的箭頭函數沒有arguments屬性,如果箭頭函數內要實現不定參,上述方式就是一個不錯的選擇了。

  2,箭頭函數

  箭頭函數實現了一種更加簡潔的書寫方式,並且也解決了關鍵字聲明方式的一些麻煩事兒。箭頭函數內部沒有arguments,也沒有prototype屬性,所以不能用new關鍵字調用箭頭函數。

  箭頭函數的書寫方式:參數 => 函數體。

1 let add = (a,b) => {
2     return a+b;
3 }
4 let print = () => {
5     console.log('hi');
6 }
7 let fn = a => a * a;
8 //當只有一個參數時,括弧可以省略,函數體只有單行return語句時,大括弧也可以省略,強烈建議不要省略它們,是真的難以閱讀

  當函數需要直接返回對象時,建議用變數保存,然後返回變數名,或用小括弧把對象包裹起來。否則將拋出錯誤。

1 var returnObj = () =>{
2     var obj = {name:'ren',age:12};
3     retufn obj;
4 };
5 //var returnObj = () => ({name:'ren',age:12});

  箭頭函數和普通函數最大的區別在於其內部this永遠指向其父級AO對象的this。

  普通函數在預編譯環節會在AO對象上添加this屬性,保存一個對象(請參照《JavaScript之深入對象(二)》)。每個普通函數在執行時都有一個特定的this對象,而箭頭函數執行時不會在自己的this屬性上添加一個新對象,而是直接引用父級AO對象上this綁定的對象。普通函數的AO對象只有在函數執行時才產生,換言之,普通函數的this是由函數執行時的環境決定。而箭頭函數的特別之處在於,當函數被定義時,就需要引用其父級AO對象的this,即箭頭函數的this由定義時的環境決定。

  根據箭頭函數的特點,不難推測:如果定義對象的方法直接使用箭頭函數,那麼函數內的this將直接指向window。

1  var age = 123;
2  let obj = {
3      age:456,
4      say:() => {
5          console.log(this.age);
6      }
7  };
8 obj.say();//123
9 //對象是沒有執行期上下文的(AO對象),定義對象的方法實際上是在全局作用域下,即window

   如果你一定要在箭頭函數中讓this指向當前對象,其實也還是有辦法的(但是沒必要這麼麻煩啊,直接使用普通函數不是更好嗎?):

 1  var age = 123;
 2  let obj = {
 3      age:456,
 4      say:function(){
 5          var fn = () => {
 6          console.log(this.age);
 7         }
 8          return fn();
 9      }
10  };
11 obj.say();//456

  我們來分析一下這是怎麼做到的:首先,我們使用obj調用say方法時,say內創建了AO對象,並且該AO對象的this屬性指向了obj(這都不明白的請回去往前複習一下我的《JavaScript之深入函數/對象》),然後,say內部又聲明瞭一個箭頭函數。我們說箭頭函數在聲明時就要強行引用父級AO的this屬性,那麼現在該箭頭函數的父級AO是誰呢?當然就是say的AO啦,所以這裡箭頭函數的this直接就綁定了obj,最後箭頭函數在執行時拿到的this,實際上就是say方法的AO.this,即obj本身。

  上面是在對象中使用箭頭函數,如果那讓你難於理解,那麼請看下麵這種方式:在普通函數中使用箭頭函數。

1 var obj = {name:'ren'};
2 function test(){
3     var fn = () => {
4         console.log(this);
5     };
6     fn();
7 }
8 test();//window
9 test.call(obj);//{name:'ren'}

  test函數在全局執行時,其this指向window,這時也產生了箭頭函數的定義,於是箭頭函數內的this也被指向了window,所以最終列印出window對象。

  當我們手動改變test函數執行時this的指向時,箭頭函數定義所綁定的this實際上也被我們修改了。所以最終列印出obj。

 

四  class(類)  

  class 作為對象的模板被引入ES6,你可以通過 class 關鍵字定義類。class 的本質依然是一個函數。

  1,創建類

 1 class Ex {//關鍵字申明方式
 2     constructor(name){
 3         this.name = name;
 4         this.say = () => {
 5             console.log(this.name);
 6         }
 7     }
 8     methods(){
 9         console.log('hello ' + this.name);
10     }
11     static a = 123;
12     static m = () => {
13         console.log(this.a);
14     };
15 }
16 //let ex = class{}  字面量方式
17 var example = new Ex('ren');
18 example.say();//'ren'
19 Ex.m();//123
20 example.methods();//'hello ren'
  constructor是創建類必須的方法,當使用new調用類創建實例時,將自動執行該方法,該方法和構造函數類似,預設返回this對象。實例的方法和屬性都定義在constructor內部。相當於構造函數的this方式。
  類保留了prototype屬性,類中的方法不需要使用function關鍵字,並且方法之間不需要逗號隔開。類中定義的方法實際上還是保存在類的prototype屬性上。
  使用static關鍵字定義類的靜態屬性和方法。類中不能定義共有屬性,要想定義實例的共有屬性還是需要使用prototype屬性:Ex.prototype.屬性名 = 屬性值。

  創建實例依然使用new關鍵字。

  2,類的繼承
  類的繼承通過extends關鍵字實現。
 1 class Person {
 2     constructor (name,age){
 3         this.name = name;
 4         this.age = age;
 5     }
 6     say(){
 7         console.log(this.name + ':' + this.age);
 8     }
 9 }
10 class Student extends Person{
11     constructor (name,age,sex){
12         super(name,age);
13         this.sex = sex;
14     }
15 }
16 var student = new Student('ren',12,'male');
17 student.name;//'ren'
18 student.sex;//'male'
19 student.say();//'ren:12'

  子類繼承自父類,不會隱式的創建自己的this對象,而是通過super()引用父類的this。這個過程和在子構造函數內使用父構造函數call(this)很像,但他們有本質的區別。另外,ES6規定,super()必須在子類的this之前執行。所以一般我們把super()放在子類constructor方法的第一行,這樣準沒錯!

 

五  非同步機制

  ES6新增了兩種實現非同步的新機制,Promise和Generator。文筆有限,怕講的不清楚,誤人子弟,請有興趣的同學去下麵的鏈接繼續學習,廖老師的教程也是受很多人推崇的,當然MDN更官方。(實際上是需要較大篇幅才能講明白,這裡就偷個懶了)

  1,Promise

  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

  https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544

  2,Generator

  https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Generator

  https://www.liaoxuefeng.com/wiki/1022910821149312/1023024381818112

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 經常會在一些網站或博客看到“深克隆”,“淺克隆”這兩個名詞,其實這個很好理解,今天我們就在這裡分析一下 。 淺拷貝 我們先以一個例子來說明js淺拷貝: 上面顯然 的值會變為 12,這就是js淺拷貝。 淺拷貝只是拷貝的指向對象的指針,本質上還是指向同一個對象。 深拷貝 同樣我們還是以一個例子來說 ...
  • 一、 在預設佈局的垂直方向上,預設情況下外邊距是是不會疊加的,會出現合併現象,誰的外邊距較大,就聽誰的;但是在水平方向就不會出現這種狀況,我們舉個例子 二、盒子模型 1.什麼是盒子模型 答:CSS盒子模型僅僅一個比較形象地比喻,HTML中所有的標簽都是盒子,我們現實生活中的物品大多都是有位置區域劃分 ...
  • 本文轉自https://www.cnblogs.com/songdongdong/p/6340373.html 在jQuery中,attr()函數和prop()函數都用於設置或獲取指定的屬性,它們的參數和用法也幾乎完全相同。 但不得不說的是,這兩個函數的用處卻並不相同。下麵我們來詳細介紹這兩個函數之 ...
  • 廢話不多說,之前寫小程式碰到了一個問題,如何在 wxml 頁面中截取數據? 1、wxs 取數據想必大家都會,不就是 substring 嗎?但是這種方法在 wxml 頁面中是無效的。 那還有 css 啊,不一樣可以做到嗎?但是個人覺得 css 復用性太差,暫不考慮。 實在不行就用 js 唄,在獲取到 ...
  • 在平時網上商城購物時,我們能夠通過放大鏡效果來使我們看圖片能夠更加的清楚,今天我就來給大家分享一下我學習的放大鏡特效 下圖是原圖的樣子 下圖是滑鼠放上去的效果 接下來我們就看一看放大鏡效果是如何實現的 1.首先我們還是先把div佈局寫出來 2.其次是css部分 3.最後是js部分代碼 ...
  • 昨天朋友圈被「請給我一面國旗@微信官方」刷屏,雖然知道是假的,但是從另一個角度來看,弄清楚如何實現更有趣。 1、canvas 這就不得不提到小程式中的 API canvas,H5 中也是有 canvas 的,不過之前也一直沒有機會用,這次正好乘機試試水。 晚上回家看了下官方文檔,網上搜了一些類似的功 ...
  • 本方法是在不改變原 js 的情況下,通過擴展方法來實現本目的 首先在 datetimebox 控制項中擴展一個 綁定雙擊事件 的方法 然後在 datetimebox 控制項中的 onShowPanel 事件中 進行綁定雙擊事件 註意:上述兩個 擴展必須 放在 載入 datetimebox 控制項 之前。 ...
  • 我們也都知道上傳圖片的樣子是這樣的(選擇前)是這樣的(選擇後)。 先在HTML設置圖片上傳 然後編輯css樣式 最後設置js上傳圖片後的變化 最終呈現出來的結果如下:選擇前選擇後。 本文屬於簡單的小白文,只是講述知識點,如有幫助,切勿複製,請自行修改使用 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...