ES6新特性在最新版谷歌浏览器上基本都能跑通,不需要什么babel就能测试了
参照文档:ES6标准入门;精选了部分重要特性
(一)let与块级作用域,const
// 块级作用域
//demo1 let代码块作用域
//1.只在let命令所在代码块有效
//2.只能在let命令之后使用该变量
{
let a = 59;
var b = 2;
}
console.log(a); //a is not defined
console.log(b);
//demo2 for语句块级作用域
//let将在每个迭代中生成一个新的作用域,使得每个迭代中的函数执行时都有不同的作用域
var a = [];
for(let i = 0;i<10;i++){
a[i] = function () {
console.log(i);
}
}
a[6]();
//demo3 {}块级作用域写法代替匿名函数
(function(){
var a = 1;
function b() {
}
})()
{
let a = 1;
let b = function() {
}
}
//demo4 const定义常量 常量值不可修改
const dd = 5000;
(二)解构赋值
// 变量的解构赋值:ES6允许按照一定模式,从数组和对象中提取值,对【变量进行赋值】,这被称为解构
//-------demo1 数组的解构赋值-------
var [a,b,c] = [1,2,3];
var [a,[b,c]] = [1,[2,3]]; //模式匹配:只要等号两边模式相同,左边的变量就会被赋予对应的值
[a,b] = [b,a]; //这种写法快速实现变量值的替换
var [f = 1] = []; //解构赋值允许通过这种写法指定默认值,如果模式匹配对应的值严格等于undefined,则默认值生效
//-------demo2 对象的解构赋值:它们几乎以同样的方式工作,仅仅是从数组变成了对象:-------
//写法1:当需要赋值的变量值与对象属性名不同
var {a:aa,b:bb} = {a:1,b:2};
//写法2:当需要赋值的变量值与对象属性名相同:属性没有顺序要求
//这里结合了对象的属性简洁表示法,实际和写法1一样
var {a,b} = {a:1,b:2}; //等效于{a:a,b:b} = {a:1,b:2}
//案例:
var jsonData = {a:1,b:2};
var {a,b} = jsonData; //提取json对象属性值
var {max,min} = Math; //将现有对象的方法快速赋值到某个变量
//指定默认值
var {x = 1} = {};
//-------demo3 字符串的解构赋值-------
var [a,b] = 'ab'; //字符串的解构赋值,字符串将被转换成一个类数组对象
var {length} = 'ab'; //读该类数组对象的length属性
//-------demo4 数值和布尔值的解构赋值-------
//解构赋值规则是,只要等号右边不是对象,就先将其转为对象
var {toString:s} = 1; //s === Number.prototype.toString 为true: 默认将等号右边的数值或布尔值转换为包装对象
//-------demo5 函数参数的解构赋值-------
//参数数组解构
function add([x,y]) {
console.log(x,y)
}
add([1,2]); //函数参数并不是一个数组,而是通过解构得到的变量x和y
//参数对象解构
function fun({a,b}) {
}
fun({a:1,b:2}); //函数参数并不是一个数组,而是通过解构得到的变量x和y
//参数默认值的两种写法,这里以对象解构为例(数组解构相同)
//写法1:解构时指定参数默认值
function fun({a = 1,b = 2}) {
console.log(a,b);
}
fun(); //相当于undefined转换为对象失败,报错
//写法2:如果函数调用时传递的实参严格等于undefined,则以等号右边默认值执行解构
function fun({a,b} = {a:1,b:2}) {
console.log(a,b);
}
fun();//1 2
//两者结合
function fun({a = 0,b = 0} = {a:1}) {
console.log(a,b);
}
fun();//1 0
(三)String扩展
// 字符串的扩展
//-------demo1
// includes:返回布尔值,表示是否找到了参数字符串
// startsWith:返回布尔值,表示参数字符串是否在源字符串的头部
// endsWith:返回布尔值,表示参数字符串是否在源字符串的尾部
var s = 'hello world';
s.startsWith('world',6); //true 从第六个字符开始匹配,是否以world作为开始字符串
s.endsWith('hello',5); //true 从第五个字符开始匹配,(前五个字符)是否以hello作为开始字结尾
s.includes('hello',6); //false 从第六个字符开始匹配,是否包含hello字符串
//-------demo2 repeat
'a'.repeat(2); //'aa' 表示将字符串重复N次
//-------demo3 模板字符串:利用反引号生成模板字符串
var str = '<ul>' +
'<li>' + a + '</li>'
+ '</ul>';
var str = `<ul>
<li>${a}</li>
</ul>`;
//模板字符串中可以执行表达式
function fn() {
return 'hello';
}
var str = `<ul>
<li>${fn()}</li>
</ul>`;
(四)Number扩展
// 数值的扩展
//demo1 Number.isInteger() 判断是否为整数
Number.isInteger(25); //true
Number.isInteger(25.2); //false
Number.isInteger(25.0); //true
Number.isInteger('25'); //false 数据类型必须是Number
//demo2 Math方法扩展——trunc:去除小数返回整数部分
Math.trunc(4.1); //4
Math.trunc(4.9); //4
Math.trunc(-4.1); //-4
Math.floor(-4.1); //-5
//demo3 Math方法扩展——sign:判断一个数到底是整数、负数还是零
Math.sign(5); //返回1
Math.sign(-5); //返回-1
Math.sign(0); //返回0
Math.sign('a'); //NaN
//demo4 新增指数运算符
//2 ** 2; //4 等效于Math.pow(2, 2)
(五)Array扩展
// 数组的扩展
//demo1 Array.from:将两类对象转为真正的数组——类数组对象(array-like object)和可遍历对象(Set Map)
let arrayLike = {
0:'a',
1:'d',
length:2
};//任何有length属性的对象都为类数组对象
let arr1 = [].slice.call(arrayLike); //ES5写法 返回['a','b']
let arr2 = Array.from(arrayLike); //ES6写法 返回['a','b']
//demo2 Array.of:将一组值转换为数组
Array.of(2, 3, 4); //[2,3,4]
Array.of(1) //[1]
new Array(1) //[undefined]
//demo3 Array.prototype.copyWithin:将指定位置的成员复制到其他位置,然后返回当前数组
// Array.prototype.copyWithin(target,start=0,end=this.length)
//target:从该位置开始替换数据
//start(可选):从该位置开始读取数据,默认0,负数为倒数
//end(可选):从该位置停止读取数据,默认为数组长度,负数为倒数
[1,2,3,4,5].copyWithin(0,3) //[4,5,3,4,5]
//demo4 Array.prototype.find/findIndex:找出第一个符合条件的数组元素(或索引)
[1,2].find(function(v,i){return v>1}); //2
[1,2].filter(function(v,i){return v>1}); //[2] 和filter的对比
//demo5 Array.prototype.fill:填充数组
[1,2,3].fill(4) //[4,4,4]
new Array(10).fill(0) //[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1,2,3].fill(4,1,2) //[1,4,3] 第二个参数为填充起始位置,第三个参数为结束位置
//demo6
//遍历方法:
//keys() 返回键名的遍历器
//values() 返回键值的遍历器
//entries() 返回键值对的遍历器
//forEach() 使用回调函数遍历每个成员
for(let i of ['a','b'].keys()){//0 1
console.log(i);
}
for(let v of ['a','b'].values()){//'a','b'
console.log(v);
}
for(let [i,v] of ['a','b'].entries()){//0 'a' 1 'b'
console.log(i,v);
}
//总结遍历数组所有方法:
var arr = [1,2,3]
arr.test = 'test'
Object.defineProperty(arr,"NOenumerable",{
//enumerable:false,
value:'enumerable false'
});
Array.prototype.Ptest = 'prototype.test'
//forEach
//1 0 2 1 3 2 :遍历数组元素;不可遍历其它属性;
//缺点:不可跳出循环
arr.forEach(function(v,i){console.log(v,i)})
//for in
//1 2 3 test Ptest: 遍历数组元素键名(索引)+自定义属性+继承属性;不可遍历非枚举属性
//缺点:键名是字符串;会遍历非数组元素属性;属性属性不可保证
for(let i in arr){console.log(i)}
//for of
//1 2 3:只返回对数组元素的遍历
for(let v of arr){
console.log(v);
}
//Object.getOwnPropertyNames
//["0", "1", "2", "length", "test", "NOenumerable"]:返回自身所有属性的数组
Object.getOwnPropertyNames(arr)
(六)Function扩展
//函数的扩展
//----函数参数默认值
//写法1:直接形参=默认值
function a(b=1,c=2){}
//写法2:结合解构赋值
function a({b,c=2}){console.log(b,c)}
a({}) //undefined 2
a({b:2}) //2 2
a() //Cannot match against 'undefined' or 'null'
//----rest参数
//rest参数搭配的变量是一个数组,该变量将多余的参数放入其中
function add(a,...vals){ //注意:rest参数必须为最后一个参数
console.log(vals)
}
add(1,2,3)
//----扩展运算符 ...
//它好比rest参数的逆运算,将一个数组(类数组,Set,Map)转为用逗号分隔的参数序列
console.log(...[1,2,3]) //1 2 3
Math.max(...[3,4,5])
//ES5 [1,2].concat(more)
//[1,2,...more]
//用于函数调用
function push(arr,...items){
arr.push(...items)
return arr
}
//伪数组转成数组
var nodeList = document.querySelectorAll('div')
var arr = [...nodeList]
//与解构结合
[a,...rest] = [1,2,3] //a:1 rest:[2,3]
//----箭头函数
//使用箭头 => 定义函数
var f = v => v
//等同于
var f = function(v){return v}
//场景1
[1,2,3].map(function(x){return x*x})
[1,2,3].map(x => x*x)
//场景2
var result = [2,4,3].sort(function(a,b){return b-a})
var result = [2,4,3].sort((a,b) => b-a})
//场景3:箭头函数this是函数定义时所在上下文
function foo(){
setTimeout(()=>{
console.log(this)
},100)
}
foo.call({})
(七)Object扩展
//----对象的扩展
//----属性(方法)简洁表示
var foo = 'bar'
var baz = {foo}
//等同于
var baz = {foo:foo}
var o = {
method(){return 'hello'}
}
//等同于
var o = {
method:function(){return 'hello'}
}
//----属性名表达式: 对象直接量中可以通过[变量]的形式设置变量名
let a = 'foo'
let obj = {
[a]:true
}
//----Object.assign(目标对象,源对象):将源对象的所有可枚举属性复制到目标对象
//只能复制自身属性,不可枚举的属性和继承的属性不会被复制
let target = {a:1}
let source1 = {b:2}
let source2 = {c:3}
Object.assign(target,source1,source2) //target:{a: 1, b: 2, c: 3}
//深度克隆
function clone(origin){
let originProto = Object.getPrototypeOf(origin)
return Object.assign(Object.create(originProto),origin)
}
//为属性指定默认值
const DEFAULTS={
a:{d:3}
}
function a(options){
let _options = Object.assign({},DEFAULTS,options)
console.log(_options)
}
//对象原型操作
let a = {m:1}
Object.setPrototypeOf(a,{n:1})
Object.getPrototypeOf(a)