let
用法类似 var
。
(() => {
for (var i = 0; i < 6; i++) {}
console.log(i); // 6
})();
(() => {
for (let i = 0; i < 6; i++) {}
console.log(i); // ReferenceError: i is not defined
})();
# 高频场景
(() => {
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
}
}
a[6](); // 10
})();
(() => {
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
}
}
a[6](); // 6
})();
# 没有 变量提升
(() => {
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
}
}
a[6](); // 10
})();
(() => {
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
}
}
a[6](); // 6
})();
# 暂时性死区
// let 声明之前使用会报错
(() => {
if (true) {
typeof undefined_save; // 不报错
typeof save; // ReferenceError: save is not defined
let save;
}
})();
# 不能重复声明
(() => {
let save = 7;
let save = 6; // SyntaxError: Identifier 'save' has already been declared
var you = 7;
var you = 6; // OK
})();
解构解析
# 普通解析
(() => {
/**
* 数组
*/
let [a,b,c] = [1, 3, 4];
console.log(a); // 1
console.log(b); // 3
console.log(c); // 4
/**
* 数组中数组
*/
let [v1, [[v2], v3]] = [1, [[2], 6]];
console.log(v1); // 1
console.log(v2); // 2
console.log(v3); // 6
/**
* 解析不到
*/
let [v4] = [];
let [v5, v6] = [6];
console.log(v4); // undefined
console.log(v5); // 6
console.log(v6); // undefined
})();
(() => {
/**
* 默认值
*/
let [v1 = true] = [];
let [v2, v3 = 'b'] = ['a'];
let [v4, v5 = 'b'] = ['a', undefined];
console.log(v1); // true
console.log(v2); // a
console.log(v3); // b
console.log(v4); // a
console.log(v5); // b
/**
* null 生效
* undefined 不生效
*/
let [v6 = 'save'] = [undefined];
let [v7 = 26] = [null];
console.log(v6); // save
console.log(v7); // null
})();
# 对象解析
普通对象
(() => {
let object = {
array: [
'Save',
{
you: 'you from anything'
}
]
};
let {array: [save, {you}]} = object;
console.log(save); // Save
console.log(you); // you from anything
})();
嵌套对象
(() => {
(() => {
let object = {};
let array = [];
({save: object.save, you: array[7]} = {save: 'Save', you: 'you'});
console.log(object.save); // Save
console.log(array[7]); // you from anything
})();
系统类对象
(() => {
/**
* Math
*/
let {log: mathLog, sin: mathSin, cos: mathCos} = Math;
console.log(mathLog);
console.log(mathSin);
console.log(mathCos);
/**
* Array
*/
let array = ["Save", "you", "from", "anything"];
let {length: count, 0: firstElement, [array.length - 1]: lastElement} = array;
console.log(count); // 4
console.log(firstElement); // Save
console.log(lastElement); // anything
/**
* String
*/
const [s,a,v,e] = "Save";
console.log(s); // S
console.log(a); // a
console.log(v); // v
console.log(v); // e
})();
String 扩展
# 模板编译
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板编译</title>
</head>
<body>
<div id="div"></div>
<script>
let template = `
<ul>
<% for(var i=0; i < data.supplies.length; i++) { %>
<li><%= data.supplies[i] %></li>
<% } %>
</ul>
`;
function compile(template) {
let evalExpr = /<%=(.+?)%>/g;
let expr = /<%([\s\S]+?)%>/g;
template = template
.replace(evalExpr, '`); \n echo( $1 ); \n echo(`')
.replace(expr, '`); \n $1 \n echo(`');
template = 'echo(`' + template + '`);';
let script =
`(function parse(data){
var output = "";
function echo(html){
output += html;
}
${ template }
return output;
})`;
return script;
}
let div = document.getElementById("div");
let parse = eval(compile(template));
div.innerHTML = parse({supplies: ["CaMnter", "Save you from anything", "魔法使"]});
</script>
</body>
</html>
Number 扩展
# Number.isNaN
Number.isNaN(...)
: 判断一个值是否为 NaN
。
(() => {
/**
* ES6
*/
console.log(Number.isNaN(NaN)); // true
/**
* ES5
*/
(function (global) {
var global_isNaN = global.isNaN;
Object.defineProperty(Number, 'isNaN', {
value: function isNaN(value) {
return typeof value === 'number' && global_isNaN(value);
},
configurable: true,
enumerable: false,
writable: true
});
})(this);
console.log(Number.isNaN(NaN)); // true
})();
# Number.isSafeInteger
Number.isSafeInteger(...)
: 来判断一个整数是否落在 -2^53 ~ 2^53 之内。
JavaScript 能够准确表示的整数范围在 -2^53 ~ 2^53 之间(不含两个端点),超过这个范围,无法精确表示这个值。
(() => {
/**
* ES6
*/
console.log(Number.isSafeInteger(9007199254740990)); // true
console.log(Number.isSafeInteger(9007199254740992)); // false
/**
* ES5
*/
Number.isSafeInteger = function (n) {
return (typeof n === 'number' &&
Math.round(n) === n &&
Number.MIN_SAFE_INTEGER <= n &&
n <= Number.MAX_SAFE_INTEGER);
}
console.log(Number.isSafeInteger(9007199254740990)); // true
console.log(Number.isSafeInteger(9007199254740992)); // false
})();
Array 扩展
# Array.of
Array.of(...)
: 方法用于将一组值,转换为数组。
(() => {
// ES6
console.log(Array.of()); // []
console.log(Array.of(undefined)); // [ undefined ]
console.log(Array.of(7)); // [ 7 ]
console.log(Array.of(6, 7)); // [ 6, 7 ]
// ES5 部署 Array.Of()
function ArrayOf() {
return [].slice.call(arguments);
}
console.log(Array.of(7)); // [ 7 ]
})();
# Array.includes
Array.prototype.includes
: 方法返回一个布尔值,表示某个数组是否包含给定的值。
(() => {
// 属于 ES7 语法
// ES6 部署 includes
const arrayIncludes = (() => Array.prototype.includes ?
(array, value) => array.includes(value) :
(array, value) => array.some(el => el === value))();
console.log(arrayIncludes(['Save', 'you', 'from', 'anything'], 'Save')); // true
})();
Function 扩展
# 参数 默认值
(() => {
const SAVE = "Save";
/**
* ES6
*/
function es6function(value = SAVE) {
console.log(value);
}
es6function(); // Save
/**
* ES5
*/
function es5function(value) {
if (typeof value === 'undefined') {
value = SAVE;
}
console.log(value);
}
es5function(); // Save
})();
# 参数 解构解析
(() => {
const SAVE = "Save";
function func({index, sign = SAVE}) {
console.log(index, sign);
}
func({index: 67, sign: 'you'}); // 67 'you'
func({index: 67}); // 67 'Save'
func({}); // undefined 'Save'
})();
# 参数可省 与 参数不可省
(() => {
/**
* 参数可省
*/
function funcA(v = undefined) {
return v;
}
funcA();
/**
* 参数不可省
*/
function throwIfMissing() {
throw new Error('Missing parameter');
}
function funcB(v = throwIfMissing()) {
return v;
}
funcB(); // Error: Missing parameter
})();
# rest 参数
rest 参数:...变量名
,代表一个数组 。
(() => {
function func(array, ...items) {
items.forEach(function