var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令生命的变量,
从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
在代码块内,使用let命令声明变量之前,变量都是不可用的,成为“暂时性死区(TDZ)”。
// 报错
function font(){
let a = 10;
var a = 10;
}
// 报错
function func(){
let a = 10;
let a = 1;
}
不能再函数内部重新生命参数
function func(arg){
let arg; //报错
}
function func(arg){
{
let arg; //不报错
}
}
防止外层代码收内层代码的影响
用来计数的循环变量泄露为全局变量
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
{{{{{ let insane = 'Hello World' }}}}};
{{{{
let insane = 'Hello World';
{let insane = 'Hello World'}
}}}};
const PI = 3.1415;
console.log(PI) //3.1415
let a = 1;
let b = 2;
let c = 3;
等同于==》
ES6:
let [a,b,c] = [1,2,3]
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError: y is not defined
let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
简写原方法:let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
const [a,b,c,d,e] = 'hello';
a // "h"
b // "e"
c // "l"
length
属性 let {length:len} = 'hello'
len //5
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
let {prop:x} = undefined;
let {prop:y} = null;
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]
map是把一个数组的元素经过处理,映射到新的数组中
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
const map = new Map();
map.set('first','hello');
map.set('second','world');
for(let [key,value] of map){
console.log(key + 'is' + value)
}
// first is hello
// second is world
//获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
}
\uxxxx
形式表示一个字符,其中xxxx
是Unicode码点 var str = "\uD842"
// 输出 "�"
str2 = "\uD842\uDFB7"
// "��"
"\u{20BB7}"
// "��"
"\u{41}\u{42}\u{43}"
// "ABC"
let hello = 123;
hell\u{6F} // 123
String.fromCodePoint(0x20BB7)
// "��"
String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'
// true
for (let codePoint of 'foo') {
console.log(codePoint)
}
// "f"
// "o"
// "o"
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
支持第二参数,表示开始搜索的位置
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
参数如果是小数,取整
'na'.repeat(2.9) // "nana"
如果repeat的参数是负数或者Infinity,会报错。
参数是 0 到-1 之间的小数,则等同于0。repeat视同为 0.
NAN
等同于0。
参数为字符串,会嫌转成数字。
'na'.repeat(-0.9) // ""
'na'.repeat(NaN) // ""
'na'.repeat('na') // ""
'na'.repeat('3') // "nanana"
'x'.padStart(10,'qw')
"qwqwqwqwqx"
如果原字符串的长度,等于或大于指定的最小长度,则返回原字符串。
'xxx'.padStart(2, 'ab') // 'xxx'
'xxx'.padEnd(2, 'ab') // 'xxx'
如果省略第二个参数,默认使用空格补全长度。
'abc'.padStart(10, '0123456789')
// '0123456abc'
'x'.padStart(4) // ' x'
'x'.padEnd(4) // 'x '
常见:数值、格式
'1'.padStart(10, '0') // "0000000001"
'12'.padStart(10, '0') // "0000000012"
'123456'.padStart(10, '0') // "0000123456"
'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
matchAll()
返回一个正则表达式在当前字符串的所有匹配
模板字符串
var html = `this is ${v.item}`;
使用反引号时:
let greeting = `\`Yo\`;
输出 greeting: "`Yo` World!"
变量名放在
${}
中大括号内可以放入任意js表达式进行运算。可以引入对象属性。可以调用函数
`${x}+${y}=${x+y}` // 1 + 2 = 3
let obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// "3"
`foo ${fn()} bar`
`Hello ${'World'}` // "Hello World"
引用方法
// 写法一
let str = 'return ' + '`Hello ${name}!`';
let func = new Function('name', str);
func('Jack') // "Hello Jack!"
// 写法二
let str = '(name) => `Hello ${name}!`';
let func = eval.call(null, str);
func('Jack') // "Hello Jack!"
alert`123` 等同于==> alert(123)
function tag(stringArr,val1,val2){
// ...
}
// 等同于
function tag(stringArr,...val){
// ...
}
+
- Number.isfinite() //检查一个数值是否为有限的
- Number.isNaN() //检查一个数值是否为NaN
全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。
判断是否为整数
Number.isInteger(25) // true
Number.isInteger(25.0) // true
Number.isInteger(25.1) // false
Number.isInteger('25') // false
Number.EPSILON ??
Math对象的扩展
Math.trunc() 去除一个数的小数部分,返回整数部分
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc(-4.9) // -4
Math.sign() 用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。
Math.cbrt() 计算一个数的立方根。
Math.cbrt(1) // 1
Math.cbrt(2) // 1.2599210498948734
Math.cbrt('8') // 2
Math.clz32() 返回一个数的 32 位无符号整数形式有多少个前导 0。
Math.clz32(0) // 32
Math.clz32(1) // 31
Math.clz32(1000) // 22
Math.clz32(0b01000000000000000000000000000000) // 1
Math.clz32(0b00100000000000000000000000000000) // 2
Math.imul() 返回两个数以 32 位带符号整数形式相乘的结果,返回的也是一个 32 位的带符号整数。
Math.imul(2, 4) // 8
Math.imul(-1, 8) // -8
Math.imul(-2, -2) // 4
Math.fround() 返回一个数的32位单精度浮点数形式。
Math.hypot(3, 4); // 5
Math.hypot(3, 4, 5); // 7.0710678118654755
Math.hypot(); // 0
Math.hypot() 返回所有参数的平方和的平方根
Math.hypot(3, 4); // 5
Math.hypot(3, 4, 5); // 7.0710678118654755
Math.hypot(); // 0
对数方法
指数运算符 **
function log(x,y = 'hello'){
console.log(x,y)
}
function f(x = 1, y) {
return [x, y];
}
f() // [1, undefined]
f(2) // [2, undefined])
f(, 1) // 报错
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
...变量名
) function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
name属性
返回该函数的函数名
var fa = function abc(){};
fa.name // "abc"
5.箭头函数 =>
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
尾调用: 指某个函数的最后一步是调用另一个函数
function f(x) {
if (x > 0) {
return m(x)
}
return n(x);
}
此例中m和n都属于尾调用,因为他们都是函数的最后一步操作
尾递归
...
)console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.querySelectorAll('div')]
// [, , ]
- 2.Array.from() 将类似数组的对象和可遍历的对象转为真正的数组
3.Array.of() 将一组值,转换为数组
5.find()和findIndex() 找出第一个符合条件的数组成员。
- 所有数组成员依次执行该回调函数,直到找出第一个函数值为true的成员,返回该成员。若没有,返回undefined
[1, 4, -5, 10].find((n) => n < 0) //5
6.fill() 使用给定值,填充一个数组。
['a','b','c'].fill(7) // [7,7,7]
接受第二个第三个参数,用于指定填充的起始位置和结束位置
['a','b','c'].fill(7,1,2) // ['a',7,'c']
- 7.entries(),keys(),values() 遍历数组
用for…of循环遍历,区别
- keys() 对键名的遍历
- values() 对键值的遍历
- entries() 对键值对的遍历
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a' 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a" 1 "b"
- 8.includes() 返回布尔值
对象的扩展
- Object.keys() Object.values() Object.entries()
- Object.keys,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键名。
- Object.values,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值。
- Object.entries,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值对数组。
let {keys, values, entries} = Object;
let obj = { a: 1, b: 2, c: 3 };
for (let key of keys(obj)) {
console.log(key); // 'a', 'b', 'c'
}
for (let value of values(obj)) {
console.log(value); // 1, 2, 3
}
for (let [key, value] of entries(obj)) {
console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}
ES7 ECMAscript2016 新特性:includes 指数操作符(冥运算)
includes:
- arr.includes(str1);
判断是否包含一个指定的值,是为true,否则为false;
- arr.includes(searchel,fromindex)
从索引处开始查找指定的值,如果为负值,按照从后往前 arr.length + fromindex的位置开始搜索,默认为0。
- 当fromindex大于等于数组长度,则返回false。该数组不会被搜索
- 当fromindex为负值,极速出的索引将所谓开始搜索指定值的位置。若果计算出的索引小于0,整个数组会被搜索
- 作为一个通用方法。可用于列数组对象。在函数的参数对象上调用includes方法。
var arr = [1,2,3]
arr.includes('2','-1') // false
arr.includes('2','-2') // true
(function(){
console.log([].includes.call(arguments,'a')); // true
console.log([].includes.call(arguments,'d')); // false
})('a','b','c');
includes 兼容性:IE11. IE低版本不支持
对比 indexOf 全兼容
let arr = [4,5,6];
if(arr.indexOf(5) !== -1){
console.log('5 存在')
}
指数操作 冥运算
- ES7 幂指数操作 **
console.log(7**3); //343
- 原方法:
function mi(base,num){
if(num === 1){
return base;
}else{
return base * mi(base,num - 1);
}
}
mi(7,3) // 输出343