ECMAScript
ECMAScript 是一种由Ecma国际 通过ECMA-262标准化的脚本程序设计语言 。这种语言在万维网上应用广泛,它往往被称为JavaScript或JScript,所以它可以理解为是JavaScript的一个标准,但实际上后两者是ECMA-262标准的实现和扩展。
LET 和 CONST
let变量
ES5 中作用域有全局作用域、函数作用域。没有块作用域的概念。
ES6 中新增了块级作用域。块作用域由 { } 包括,if语句和 for语句里面的{ }也属于块作用域。
let声明的变量在let命令所在的代码块中有效。不存在变量提升,只能先声明后使用。
如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。
var a = 1;
{
a = 2; //ReferenceError
let a = 'a';
console.log(a); //'a';
}
在相同块级作用域中,不能用let重复声明同一变量。即使已存在的变量是通过var声明的。
let a = 1; let a = 2; //报错
let a = 1; var a = 2; //报错,var声明有变量提升作用
const常量
声明常量必须马上赋值且不能再改变。const和let有类似的特点:在块级作用域内有效,声明不提升,存在暂存死区,不可重复声明。
const let 和 var的区别
var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。
解构赋值
从数组和对象中提取值,对变量进行赋值,称为解构赋值(destructuring)
数组解构赋值
数组的解构赋值,按照对应顺序赋值,如果值数量超出则多余的值被抛弃,如果值不够则为undefined
let arr = [1, [2, 3]];
let [a, [b, c]] = arr;
console.log(a,b,c);
let arr = [, [2, 3]];
let [a='123', [b, c]] = arr;
console.log(a,b,c);
//ES5非解构赋值的情况
let arr = [0,1,2];
let a = arr[0];
let b = arr[1];
let c = arr[2];
不完全解构
let [a = 1, b] = []; // a = 1, b = undefined
剩余运算解构
let [a, ...b] = [1, 2, 3];
//a = 1
//b = [2, 3]
解构默认值
//当要解构的变量 为undefined时 取默认值 否则取解构值
let [a = 2] = [undefined]; // a = 2
对象的解构赋值
1.对象的解构赋值和数组的解构赋值其实类似,但是数组的数组成员是有序的
而对象的属性则是无序的,所以对象的解构赋值简单理解是等号的左边和右边的结构相同。
// 对象的解构赋值是根据key值进行匹配
let { name:Name,age } = { name:'swr',age:28 }
console.log(Name) // 'swr'
console.log(age) // 28
字符串扩展方法
for...of方法
const exp= ['mini', 'mani', 'mo'];
for (const value of exp) {
console.log(value)
}
startsWidth() endsWidth() includes()。
let s = 'hello word!';
s.startsWith('hello'); //true
s.endsWidth('word'); //false
s.includes('o'); //true
includes和indexOf的区别:
1)includes可以判断数组中有NaN indexOf不行
2)includes返回bool类型、indexOf返回数值
var ary = [NaN];
console.log(ary.indexOf(NaN))//-1
console.log(ary.includes(NaN))//true
at()
用于返回给定位置的字符,对于编码大于0xFFFF的字符用at()方法。
//es5 charAt()方法 对于编码大于0xFFFF字符无法解析
'ab'.charAt(0) //'a'
'a'.charAt(0) //'\uD842'
'a'.at(0) //''
repeat()
repeat 方法,就是对一个字符串重复多次,它接受一个参数,重复的次数,返回一个新字符串。
let msg = "Hello";
console.log(msg.repeat(4)) //HelloHelloHelloHello
模版字符串
用反引号【`】标识,它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
普通用法
let name = 'zq';
`your name is ${name}`;
模版字符串中空格和缩紧都会被保留,可以用trim()方法消除。
`
- 123
-
`.trim();
如果在模板字符串中需要使用反引号,则前面需要用反斜杠转义
let greeting = `\`Yo\` World!`; // `Yo` World!
数值相关扩展方法
新增三角函数
Math.sinh(x) //返回x的双曲正弦
Math.cosh(x) //返回x的双曲余弦
Math.tanh(x) //返回x的双曲正切
Math.asinh(x) //返回x的反双曲正弦
Math.acosh(x) //返回x的反双曲余弦
Math.atanh(x) //返回x的反双曲正切
ES6新增了指数运算符**
let a = 2;
a = a**3; //8
//可以简写成 a **= 3
a = Math.pow(a,3);//传统写法
函数的扩展
函数参数可设置默认值
function (x = 1) {}
function (x, x=1) {} //报错
函数参数是默认声明的,不能用let或const再次声明,可以用var再次声明]
function (x) {
let x = 1; //报错
var x = 1; //正常
}
拓展运算符
ES6 引入 拓展运算符(形式为【... +变量名】),用于获取函数的多余参数。
function show(...a){
console.log(a); // [14, 12, 54, 33, 22]
}
show(14,12,54,33,22);
扩展运算符可以简写数组拼接。
// 以往拼接数组的方式
let arr1 = [1,2,3]
let arr2 = [4,5,6]
let arr3 = arr1.concat(arr2)
console.log(arr3) // [ 1, 2, 3, 4, 5, 6 ]
// 扩展运算符拼接方式
let arr1 = [1,2,3]
let arr2 = [4,5,6]
let arr3 = [...arr1,...arr2]
console.log(arr3) // [ 1, 2, 3, 4, 5, 6 ]
拓展运算符解决数组引用复制问题。
let a = [14,12,54,33,22];
let b = a; // 相当于copy
a.push(44);
console.log(a); // [14, 12, 54, 33, 22, 44]
console.log(b); // [14, 12, 54, 33, 22, 44]
let a = [14,12,54,33,22];
let b = [...a];
a.push(44);
console.log(a); // [14, 12, 54, 33, 22, 44]
console.log(b); // [14, 12, 54, 33, 22]
name属性
函数的name属性,返回该函数的函数名。如果将一个匿名函数赋值给一个变量,ES5 的name属性,会返回空字符串,而 ES6 的name属性会返回实际的函数名。
let fn = () => {
let fn1 = function (){}
//es5
fn1.name //''
//es6
fn.name //'fn'
箭头函数
箭头函数是ES6之后较之前函数更为简洁的一种函数书写方式
箭头函数不绑定this,导致内部的this就是指向外层代码块的this
var a = 20;var obj = {
a: 10,
b: () => {
console.log(this.a); //undefined
console.log(this); //window
},
c: function() {
console.log(this.a); //10
console.log(this); //obj{...}
}
}
obj.b();
obj.c();
箭头函数的书写
使用 var、let、const 定义function
参数2-1. 没有参数:需要写小括号 ' ( ) '占位2-2. 一个参数:可以不加小括号直接写2-3. 多个参数:参数写在小括号 ' ( ) ' 里,用逗号隔开
箭头 ' => '
函数体写在箭头后面4-1. 一条语句:可以不加花括号直接写4-2. 多条语句:将语句放入花括号中' { } '
//ES5
var fn1 = function(){
console.log('fn1')
}
//ES6
var fn1 = (res)=>{
console.log(res)
}
//执行函数
fn1() // -> fn1
Module模块
ES6 模块通过export命令显式指定输出的代码,再通过import命令输入。使用模块自动采用严格模式
export
export 用于规定模块的对外接口,输出变量,函数,类。
//写法1
export let a = 1;
export function b () {};
//写法2
let a = 1;
function b () {};
export {a, b};
//报错
let a = 1;
export a;
通常输出的变量就是本来的名字,可以用 as 修改。
function a () {};
let b = 1;
export {
a as fnA,
b as vB
};
export输出的接口和模块内部的变量是动态绑定关系,变量值改变,通过接口获取的值也相应改变。
//test.js
export let a = 1;
setTimeout(() => a=2, 1000);
import {a} from './test'
//a = 1, 1s后变成2
export必须处于模块顶层,如果处于块级作用域会报错。import也是如此。
function () {
export let a = 1; //报错
}
import
使用import加载模块
import {a, b} from './test'
import后跟一个大括号,括号内指定需要导入的变量,变量名需对应。但可以通过as修改。
import {a as vA, b as vB} from './test';
import后的from用来指定模块的路径,绝对路径或相对路径,.js可以省略。如果模块有配置文件,则不带路径。
import有提升效果,会提升到模块头部,先执行。
由于import是静态执行,不能使用表达式和变量。比如from后的路径不能用一个变量代替。
import会执行所加载的模块,可以直接跟模块名。但多次加载相同模块只执行一次,import语句是单例模式。
import 'module_name';
import {a} from './test';
import {b} from './test';
//等同于
import {a,b} from './test';