ECMAScript 6的一些注意點 第一部分

 

什麼是"暫時性死區"?

在代碼塊內,使用let命令聲明變量之前,該變量都是不可用的。

var tmp = 123;
let tmp;    //報錯

typeof a;   //報錯
let a = 1;

// 不報錯
var x = x;
// 報錯
let x = x;
// ReferenceError: x is not defined

如果區塊中存在letconst命令,這個區塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會報錯。

暫時性死區的本質就是,只要一進入當前作用域,所要使用的變量就已經存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現,纔可以獲取和使用該變量。

塊級作用域

1、外層作用域無法讀取內層作用域的變量。

{{{{
  {let insane = 'Hello World'}
  console.log(insane); // 報錯
}}}};

2、避免在塊級作用域內聲明函數。如果確實需要,也應該寫成函數表達式,而不是函數聲明語句。

// 函數聲明語句
{
  let a = 'secret';
  function f() {
    return a;
  }
}

// 函數表達式
{
  let a = 'secret';
  let f = function () {
    return a;
  };
}

3、ES6 的塊級作用域允許聲明函數的規則,只在使用大括號的情況下成立,如果沒有使用大括號,就會報錯。

// 不報錯
'use strict';
if (true) {
  function f() {}
}

// 報錯
'use strict';
if (true)
  function f() {}

const

1、只在聲明所在的塊級作用域內有效。

if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined

2、一旦聲明,常量的值就不能改變。

3、只聲明不賦值,就會報錯。

4、同樣存在暫時性死區,只能在聲明的位置後面使用。

5、const只能保證指針是固定的(即總是指向另一個固定的地址),至於它指向的數據結構是不是可變的,不能完全控制。

const foo = {};

// 爲 foo 添加一個屬性,可以成功
foo.prop = 123;
foo.prop // 123

// 將 foo 指向另一個對象,就會報錯
foo = {}; // TypeError: "foo" is read-only

const a = [];
a.push('Hello'); // 可執行
a.length = 0;    // 可執行
a = ['Dave'];    // 報錯

數組解構

  1. 如果等號右邊不是可遍歷結構,那麼將會報錯。
  2. 只要某種數據結構存在Iterator接口,都可以進行解構,Set,生產函數等。
let [a] = 1;
let [a] = false;
let [a] = NaN;
let [a] = undefined;
let [a] = null;
let [a] = {}

對象解構

  1. 變量必須與屬相同名
  2. 如果不同名:(真正被賦值的是後者,而不是前者。)
let {foo:baz} = {foo:"aaa" , bar:"bbb"};
baz // "aaa"

如果要將一個已經聲明的變量用於解構賦值,請不要將花括號放在行首:

let x ;
({x} = {x:1});

可以方便的將現有對象的方法賦值到某個變量上:

//簡化console.log
const {log} = console;
log('簡化log')
//Math
let {sin} = Math;

字符串解構

字符串解構時被轉換成了一個類似數組的對象,可以讀取length屬性


字符串拓展

3個查詢是否包含字符串的新方法:

  • includes():返回布爾值,表示是否找到了參數字符串。
  • startsWith():返回布爾值,表示參數字符串是否在原字符串的頭部。
  • endsWith():返回布爾值,表示參數字符串是否在原字符串的尾部。
  • 它們都支持第二個參數,表示開始搜索的位置。

讓字符串重複n次:

  • xxx.repeat(n),返回一個新的字符串,參數是 0 到-1 之間的小數,則等同於 0,0 到-1 之間的小數,取整以後等於-0,參數NaN等同於 0。

ES2017引入了補全字符串長度功能,如果某個字符串不夠指定長度,會在頭部或者尾部補全

  • padStrat() , 用於頭部補全,常見用途:爲數值補全位數,另一個用途是提示字符串格式
  • '12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
    '09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
  • padEnd() , 用於尾部補全
  • 一共接受兩個參數,第一個參數補全生效的最大長度,第二個參數是用來補全的字符串
  • 如果原字符串的長度,等於或者大於最大長度,補全不生效,返回源字符串。
  • 如果用來不全的字符串與原字符串長度和超出最大長度,則截去超出位數後的補全字符串。
  • 省略第二參數,空格自動補充。

返回正則表達式在當前字符串的所有匹配:

matchAll();


模板字符串 -- 編譯模板詳解

首先需要了解一些知識(正則):

  • ( ) 標記一個子表達式的開始和結束位置,子表達式可以獲取供以後使用。要匹配這些字符,請使用 \( 和 \)。

  • .  匹配除換行符 \n 之外的任何單字符。要匹配 . ,請使用 \. 。

  • ? 匹配前面的子表達式零次或一次,或指明一個非貪婪限定符。要匹配 ? 字符,請使用 \?。

  • + 匹配前面的子表達式一次或多次。要匹配 + 字符,請使用 \+。

  • \ s 匹配任何空白字符,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。注意 Unicode 正則表達式會匹配全角空格符。

  • \S  匹配任何非空白字符。等價於 [^ \f\n\r\t\v]。

  • replace中的$1代表什麼? $1是正則裏的捕獲,就是前面的(.*?)裏的東西

  • eval()是什麼? eval() 函數可計算某個字符串,並執行其中的的 JavaScript 代碼

自己寫的簡化版例子:

全部代碼:

 let template = `
            <p>
                <@ name @>
            </p>
    `;
    function complate(template){
    let reg = /<@(.+?)@>/g;
    template = template.replace(reg,'`) \n javas($1) \n  javas(`');
    template = 'javas(`' + template + '`)';
    let script = `
    (function parse(name){
            var output = '';
            function javas(html){
                output+=html;
            }
            ${template};
            return output;
    })    
    `
    return script;
}
let parse = eval(complate(template));
document.querySelector('div').innerHTML = parse('DEMO1')

解析:

//首先 有這樣一個自定義模板
let template = `
<p> <@name@></p>`;

如果想把它轉化爲可解析的模板,需要將其轉化爲JavaScript表達式字符串,如下:

javas(`<p>`) 
javas( name ) 
javas(`</p>`)

步驟:

//首先 需要使用字符串的replace方法,通過正則更改<@@>
let reg = /<@(.+?)@>/g;
template = template.replace(reg,'`) \n javas($1) \n javas(`');

得到結果:


<p>`) 
javas( name ) 
javas(`</p>

可以看到拼接並不完全,接下來:

template = 'javas(`' + template + '`)';
//拼接完即可拿到:
/*
javas(`<p>`) 
javas( name ) 
javas(`</p>`)
*/

拼接完成以後,需要將template放在一個函數中返回:

let script = `
(function parse(name){
    let output = '';
    function javas(html){
        output+=html;
    }
    ${template};
    return output;
})
`;

至此已完成大半,下面將其封裝成函數:

function complate(template){
    let reg = /<@(.+?)@>/g;
    template = template.replace(reg,'`) \n javas($1) \n  javas(`')
    template = 'javas(`' + template + '`)';
    let script = `
    (function parse(name){
            var output = '';
            function javas(html){
                    output+=html;
            }
            ${template};
            return output;
    })    
    `
    return script;
}

最後調用:

let parse = eval(complate(template)); //調用return的script模板字符串
document.querySelector('div').innerHTML = parse('DEMO1');    //傳入name值渲染到div

輸出一下script看起來更直觀:

(function parse(name){
     var output = '';
     function javas(html){
        output+=html;
     }
     javas(`<p>`) 
     javas( name ) 
     javas(`</p>`);
     return output;
})    

可以看到這裏進行的操作:

  • 定義parse方法用來傳入name和調用,定義javas方法,傳入參數即爲模板字符串和變量,拼接到空字符串上返回,這樣就可以得到正常的html結構,最後通過eval()執行函數

output的輸出:


            <p>
               DEMO1
            </p>
    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章