javascript es規範 發展

ES5

ES5只有全局作用域和函數作用域,沒有塊級作用域
ES5規定,函數只能在頂層作用域和函數作用域之中聲明,不能在塊級作用域聲明
ES5提供String.fromCharCode方法,用於從碼點返回對應字符
ES5對字符串對象提供charAt方法
ES5不允許此時使用第二個參數,添加修飾符,否則會報錯
ES5 數組forEach(), filter(), every() 和some()都會跳過空位
ES5 數組map()會跳過空位,但會保留這個值
ES5 數組join()和toString()會將空位視爲undefined,而undefined和null會被處理成空字符串
從ES5開始,函數內部可以設定爲嚴格模式

ES6

ES6新增了let命令,用來聲明變量,類似 javascript var
ES6 規定,塊級作用域之中,函數聲明語句的行爲類似於let,在塊級作用域之外不可引用
ES6的塊級作用域允許聲明函數的規則,只在使用大括號的情況下成立,如果沒有使用大括號,就會報錯
ES6開始,全局變量將逐步與頂層對象的屬性脫鉤。
ES6解構賦值,從數組(不是可遍歷的結構-Iterator -)中提取值,按照對應位置,對變量賦值,如果解構不成功,變量的值就等於undefined
ES6解構賦值,如果解構不成功,變量的值就等於undefined
ES6解構賦值允許指定默認值
ES6對象結構賦值,對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值
ES6內部使用嚴格相等運算符(===)
ES6加強了對Unicode的支持,並且擴展了字符串對象
ES6爲字符串添加了遍歷器接口(Iterator)
ES6改變了這種行爲。如果RegExp構造函數第一個參數是一個正則對象,那麼可以使用第二個參數指定修飾符
ES6 正則擴展返回的正則表達式會忽略原有的正則表達式的修飾符,只使用新指定的修飾符。
ES6對正則表達式添加了u修飾符,含義爲“Unicode模式”
ES6提供了二進制和八進制數值的新的寫法,分別用前綴0b(或0B)
ES6引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER這兩個常量,用來表示這個範圍的上下限。
ES6提供三個新的方法——entries(),keys()和values()——用於遍歷數組
ES6則是明確將空位轉爲undefined
ES6擴展運算符(…)也會將空位轉爲undefined
ES6 數組遍歷for…of循環也會遍歷空位
ES6允許爲函數的參數設置默認值,即直接寫在參數定義的後面
ES6引入rest參數(形式爲“…變量名”)
ES6 rest參數之後不能再有其他參數(即只能是最後一個參數),否則會報錯
ES6 函數的length屬性,不包括rest參數。
ES6 擴展運算符(spread)是三個點(…)。它好比rest參數的逆運算
ES6允許使用“箭頭”(=>)定義函數
ES6也是如此,第一次明確規定,所有ECMAScript的實現,都必須部署“尾調用優化”
ES6尾遞歸的實現,往往需要改寫遞歸函數,確保最後一步只調用自身
ES6的尾調用優化只在嚴格模式下開啓,正常模式是無效的

ES 2017

ECMAScript 2017將允許函數的最後一個參數有尾逗號(trailing comma)

ES7

ES7推出了字符串補全長度的功能。

'6'.padStart(2, '0') // '06'  String s=String.format("%02d", 1);// java
'133'.padEnd(11, '*') // '********133'
'133'.padEnd(11, '*') // '133********'

語調符號和重音符號表示

許多歐洲語言有語調符號和重音符號。js爲了表示他們?

// '\u01D1'==='\u004F\u030C' //false  js   無法識別
'\u01D1'.normalize() === '\u004F\u030C'.normalize()  // js 可以識別

ES6變量賦值

// 解構賦值
var [a, b, c] = [1, 2, 3];
var [a2, b1, c1] = [1, 2, 3];
var [head, ...tail] = [1, 2, 3, 4];
var { foo, bar } = { foo: "aaa", bar: "bbb" };
var { bar, foo } = { foo: "aaa", bar: "bbb" };

ES6 let 和 const

let不像var那樣會發生“變量提升”現象(js engine 在渲染時先掃描 var 和 function 聲明,實現一個變量聲明提升)
let聲明的變量就“綁定”(binding)這個區域,不再受外部的影響(不用考慮變量聲明重複問題)
let不允許在相同作用域內,重複聲明同一個變量,並且嚴格遵循先聲明後使用規則
const聲明一個只讀的常量
const一旦聲明變量,就必須立即初始化,不能留到以後賦值,並嚴格遵循先聲明後使用得原則

// let  和 const
const [a, b, c, d, e] = 'hello';
let {length : len} = 'hello';
const add = ([x, y])=>{
  return x + y;
}

頂層對象

在瀏覽器環境指的是window對象,在Node指的是global對象。
頂層對象的屬性與全局變量掛鉤,被認爲是JavaScript語言最大的設計敗筆之一。
提案:在語言標準的層面,引入global作爲頂層對象。也就是說,在所有環境下,global都是存在的,都可以從它拿到頂層對象。

var a=1
window.a ==1
let a1 =1  // 同時用  var  和 let 聲明同名變量
window.a1

字符串擴展

codePointAt方法返回的是碼點的十進制值,如果想要十六進制的值,可以使用toString方法轉換一下

var  s = "\uD842\uDFB7"
String.fromCodePoint('0x20BB7')
'abc'.charAt(0) // "a"
// 字符串遍歷
var s = '𠮷a';
//s.codePointAt(0).toString(16) // "20bb7"
for(let item of s ){
	let value = item.codePointAt(0).toString(16)
	console.log(value);
}
// 常用判斷場景: 字符串以什麼開頭,以什麼結尾,包含
//這三個方法都支持第二個參數,表示開始搜索的位置
var s = 'Hello world!';
s.startsWith('world', 6) // true 從第n個位置直到字符串結束。
s.endsWith('Hello', 5) // true 針對前n個字符
s.includes('Hello', 6) // false 從第n個位置直到字符串結束。

//  常用場景:清空字符串
//  參數如果是小數,會被取整。
//  如果repeat的參數是負數或者Infinity,會報錯。
//  如果參數是0到-1之間的小數,則等同於0
//  0到-1之間的小數,取整以後等於-0,repeat視同爲0。
//  參數NaN等同於0。

'na'.repeat(0) // ""  

模板字符串

模板字符串(template string)是增強版的字符串,用反引號(`)標識
模板字符串中嵌入變量,需要將變量名寫在${}中
如果,大括號中是一個對象,將默認調用對象的toString方法

var name = "Martin", time = "today";
console.log(`Hello ${name}, how are you ${time}?`);

let str = '(name) => `Hello ${name}!`';
// let func = new Function('name', str);
let func = eval.call(null, str);
func('Jack') // "Hello Jack!"

標籤模板

“標籤”指的就是函數,緊跟在後面的模板字符串就是它的參數
tag函數的第一個參數是一個數組
“標籤模板”的一個重要應用,就是過濾HTML字符串,防止用戶輸入惡意內容
標籤模板的另一個應用,就是多語言轉換(國際化處理)

console.log`123`


var siteName = 'PHJRSTBT';
var visitorNumber = '12';
//const i18n =()=>{}
//  i18n 是一個函數
`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`


const SaferHTML = (templateData)=> {
  var s = templateData[0];
  for (var i = 1; i < arguments.length; i++) {
    var arg = String(arguments[i]);

    // Escape special characters in the substitution.
    s += arg.replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");

    // Don't escape special characters in the template.
    s += templateData[i];
  }
  return s;
}

var sender = '<script>alert("abc")</script>'; // 惡意代碼
var message = SaferHTML`<p>${sender} has sent you a message.</p>`;

ES6 Number擴展

Number.isFinite(15); // true
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false

Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false

Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false


Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false


Number.isNaN(9/NaN) // true
Number.isNaN('true'/0) // true
Number.isNaN('true'/'true') // true


//逐步減少全局性方法,使得語言逐步模塊化。
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45


Number.isInteger(25) // true
Number.isInteger(25.0) // true
Number.isInteger(25.1) // false
Number.isInteger("15") // false
Number.isInteger(true) // false

Number.EPSILON和 安全範圍

JavaScript能夠準確表示的整數範圍在-253到253之間(不含兩個端點),超過這個範圍,無法精確表示這個值
ES6引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER這兩個常量,用來表示這個範圍的上下限

Math.pow(2, 53) // 9007199254740992
Math.pow(2, 53) === Math.pow(2, 53) + 1
Number.EPSILON // 新增一個極小的常量  2.220446049250313e-16
Number.EPSILON.toFixed(20)  // '0.00000000000000022204'

Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1 // true
Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER // true

Number.isSafeInteger('a') // false
Number.isSafeInteger(null) // false
Number.isSafeInteger(NaN) // false
Number.isSafeInteger(Infinity) // false
Number.isSafeInteger(-Infinity) // false

Number.isSafeInteger(3) // true
Number.isSafeInteger(9007199254740990) // true
Number.isSafeInteger(Number.MIN_SAFE_INTEGER) // true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER) // true

ES6 正則擴展

字符串對象正則方法:match()、replace()、search()和split()

var s = '𠮷';
var regex = /^\uD83D/.test('\uD83D\uDC2A') // 判斷是否是 Unicode 字符
var regex = /^.$/u.test(s) // true,如果不添加u修飾符,正則表達式就會認爲字符串爲兩個字符,從而匹配失敗。
new RegExp(/abc/ig, 'i').flags // es6 正則擴展,覆蓋更新原來得修飾符,只使用新指定的修飾符

ES6 數組擴展

// 數字轉數字數組
const sortNumbers = (...numbers) => numbers.sort();
sortNumbers(2, 5, 3) // 10
(function(...a) {}).length  // 0
console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5,該運算符主要用於函數調用
Math.max(...[14, 3, 77])

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Array.prototype.push.apply(arr1, arr2);
arr1.push(...arr2);
// ES6 合併數組
[1, 2, ...more]
// ES6 生成數組
[a, ...rest] = list

ES6 方法綁定

// 如果雙冒號左邊爲空,右邊是一個對象的方法,則等於將該方法綁定在該對象上面。
let log = ::console.log; // bind 方法

尾遞歸

函數調用自身,稱爲遞歸。如果尾調用自身,就稱爲尾遞歸。

// 解決堆棧溢出

function factorial(n, total) {
  "use strict";
  if (n === 1) return total;
  return factorial(n - 1, n * total);
}
factorial(5, 1) // 120

function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
  "use strict";
  if( n <= 1 ) {return ac2};
  return Fibonacci2 (n - 1, ac2, ac1 + ac2);
}
Fibonacci2(100) // 573147844013817200000
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章