一.let和const
我们通常用 let 和 const 来声明,let 表示变量、const 表示常量。
1.没有变量提升
console.log(a);let a = 4;// a is not defined复制代码
2.不能重复申明
let a = 4;let a = 5;console.log(a);// Identifier 'a' has already been declared复制代码
3.具有块级作用域(由花括号包裹的区域)
for(let i = 0; i < 3; i++){ console.log(i); //0 1 2 } console.log(i); //i is not defined复制代码
4.临时失效区(暂时性死区)
JS引擎扫描代码时,如果发现变量声明,用var声明变量时会将声明提升到函数或全局作用域的顶部。但是 let或者const,会将声明关进一个小黑屋也是TDZ(暂时性死区),只有执行到变量声明这句语句时,变量才会从小黑屋被放出来,才能安全使用这个变量。
var tt=123 if(true){ console.log(tt)//tt is not defined let tt=456; }复制代码
一道面试题:
var funcs = [] for (var i = 0; i < 10; i++) { funcs.push(function() { console.log(i) }) } funcs.forEach(function(func) { func() })复制代码
结果呢,就是打印十个10,怎样才能打印出0到9呢?我们可以这样改。
const funcs = [] for (let i = 0; i < 10; i++) { funcs.push(function() { console.log(i) }) } funcs.forEach(func => func())复制代码
const 声明的变量是常量,意思就是它的值被设置完成后就不能再修改了。 如果 const 的是一个对象,对象所包含的值是可以被修改的。就是对象所指向的地址不能改变,而变量成员是可以修改的。
const tt={name:"wangcai"};tt.name="xiaoming";console.log(tt.name)//xiaoming复制代码
二.箭头函数
function() 函数的简写表示法,但它不绑定 this。
var object = { name: "wangcai", arrowGetName: () => this.name, regularGetName: function() { return this.name }, arrowGetThis: () => this, regularGetThis: function() { return this }}console.log(this.name)//console.log(object.arrowGetName());//console.log(object.arrowGetThis());//windowconsole.log(this)//windowconsole.log(object.regularGetName());//wangcaiconsole.log(object.regularGetThis());//object复制代码
三.模板字符串
如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中。
const t="hello" console.log(`hh${t}`) //hhhello复制代码
console.log(`hahhah`)////hahhah//复制代码
1.trim
除去字符串空格的。
trim 左右空格都是去掉
trimLeft 左空格去掉
trimRight 右空格去掉
2.repeat
3.includes
var str="abc"console.log(str.includes("a"))//true复制代码
4.startsWith和endsWidth
var str="abc def"console.log(str.startsWidth("abc"))//trueconsole.log(str.endsWidth("def"))//true复制代码
5.padStart和padEnd
var str="abc def"console.log(str.padStart(15,"*"))//"********abc def"复制代码
var s=4console.log(s.toFixed(2))//4.00console.log(s.toFixed(2).padStart(5,"0"))//04.00复制代码
四.解构赋值
//对象 let people = { name: 'lux', age: 20 } const { name, age } = people console.log(`${name} --- ${age}`) //lux---20 //数组 const color = ['red', 'blue'] const [first, second] = color console.log(first) //'red' console.log(second) //'blue'复制代码
function f(x, y=12) { return x + y;}console.log(f(3))//15console.log(f(3,2))//5复制代码
如果解构不成功,变量的值就等于undefined。如下:
let [foo] = [];let [bar, foo] = [1];复制代码
foo的值都会等于undefined。
let [x = 1, y = x] = []; console.log(x, y) // x=1; y=1 let [a = 1, b = a] = [2]; console.log(a, b) // x=2; y=2 let [e = 1, f = e] = [1, 2]; console.log(e, f) // x=1; y=2 let [t = d, d = 1] = []; console.log(t, d) // ReferenceError: d is not defined复制代码
上面最后一个表达式之所以会报错,是因为x用y做默认值时,y还没有声明。
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = 'hello';a // "h"b // "e"c // "l"d // "l"e // "o"复制代码
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
let {length : len} = 'hello';len // 5复制代码
五.扩展运算符
let arr=[1,2,3] let arr2=[...arr] console.log(arr2) //[1, 2, 3] arr[0]=666 console.log(arr2) //[1, 2, 3]复制代码
数组的复制---这里是浅拷贝
可以利用扩展运算符,把类数组转成数组
把一个类数组转成数组有如下几种方式:
Array.prototype.slice.call();
Array.from();
[...类数组对象]
//数组 const number = [1,2,3,4,5] const [first, ...rest] = number console.log(rest) //2,3,4,5 //对象 const user = { username: 'lux', gender: 'female', age: 19, address: 'peking' } const { username, ...rest } = user console.log(rest) //{ "address": "peking", "age": 19, "gender": "female"}复制代码
const first = { a: 1, b: 2, c: 6, } const second = { c: 3, d: 4 } const total = { ...first, ...second } console.log(total) // { a: 1, b: 2, c: 3, d: 4 }复制代码
有重复的属性名,会覆盖。
六.严格模式
之前学习的JS,语法非常灵活,JS中这个灵活的特性,弊大于利。后来增加了严格模式。使用严格模式的目的:规则,提高编译效率。
怎么去启动严格模式: "use strict"
列举如下几条:
在严格模式下不能使用没有var的变量。
在严格模式下不能8进制的数字。
在严格模式下不能把函数定义在if语句中。
"use strict";if(true){ function f(){ console.log("f.....") }}f();//f is not defined复制代码
在严格模式下函数不能有重名的形参
"use strict"; function f(a,a){ console.log("f.....") }f();// Uncaught SyntaxError: Duplicate parameter name not allowed in this context复制代码
arguments不会自动反映函数参数的变化
"use strict";function f(a,b){ console.log(a,b) // 1 2 console.log(arguments[0],arguments[1]) //1 2 arguments[0]=111 arguments[1]=222 console.log(a,b) //1 2 console.log(arguments[0],arguments[1]) //111 222}f(1,2);复制代码
不能删除不可删除的属性,否则报错
禁止this指向全局对象
"use strict"; function f(){ console.log(this) }f();//undefined复制代码
七.set
ES6 提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。
放一个数组
var s1=new Set([1,2,3,"true"])console.log(s1)//复制代码
结果为:
放一个对象
使用add()来添加,遍历时,使用for each或者for of
var s1=new Set()s1.add(1)s1.add(2)s1.add(3)s1.forEach(item=>console.log(item))//1 2 3复制代码
set不是数组,是一个像对象的数组,是一个伪数组。Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。
操作方法(用于操作数据)
add(value):添加某个值,返回 Set 结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除所有成员,没有返回值。
s.add(1).add(2).add(2);// 注意2被加入了两次s.size // 2s.has(1) // trues.has(2) // trues.has(3) // falses.delete(2);s.has(2) // false复制代码
遍历方法(用于遍历成员)
keys() 返回键名的遍历器
values() 返回键值的遍历器
entries() 返回键值对的遍历器
forEach() 使用回调函数遍历每个成员
keys方法、values方法、entries方法返回的都是遍历器对象。由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。
let set = new Set(['red', 'green', 'blue']);for (let item of set.keys()) { console.log(item);}// red// green// bluefor (let item of set.values()) { console.log(item);}// red// green// bluefor (let item of set.entries()) { console.log(item);}// ["red", "red"]// ["green", "green"]// ["blue", "blue"]复制代码
八.map
Map 类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
const m = new Map();const o = {p: 'Hello World'};m.set(o, 'content')m.get(o) // "content"m.has(o) // truem.delete(o) // truem.has(o) // false复制代码
const map = new Map();map.set(['a'], 555);map.get(['a']) // undefined复制代码
内存地址不一样,所以是两个值,返回undefined。
Map 结构的实例有以下属性和操作方法。
属性
size
size属性返回 Map 结构的成员总数。
const map = new Map();map.set('foo', true);map.set('bar', false);map.size // 2复制代码
set(key, value)
set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新。
get(key)
get方法读取key对应的键值,如果找不到key,返回undefined。
has(key)
has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
delete(key)
delete方法删除某个键,返回true。如果删除失败,返回false。
clear()
clear方法清除所有成员,没有返回值。
操作方法
keys():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回所有成员的遍历器。
forEach():遍历 Map 的所有成员。
map的操作方法和set类似,就不上代码啦。
九.class
从形式上,向主流的面向对象的语言靠拢。我们以前都是创建构造器,然后去new构造器,构造器就相当于一个类,在ES6中,就可以使用class来创建对象了。
function Nplayer(name,age,height){ this.name=name; this.height=height this.age=age}Nplayer.prototype.say=function(){ console.log(`我是${this.name},是NBA球员`)}var p1=new Nplayer("库里","30","191")p1.say();//我是库里,是NBA球员复制代码
我们可以用class这样写:
class Nplayer { constructor(name, age, height) { this.name = name; this.height = height this.age = age } say() { console.log(`我是${this.name},是NBA球员`) } } var p1 = new Nplayer("库里", "30", "191") p1.say(); //我是库里,是NBA球员复制代码
使用extends实现继承
注意:使用 extends 关键字来实现继承
在子类中的构造器 constructor 中,必须要显式调用父类的 super 方法,如果不调用,则 this 不可用
//父类 class Nplayer { constructor(name, age, height) { this.name = name; this.height = height this.age = age } say() { console.log(`我是${this.name},是NBA球员`) } } //子类 class MVP extends Nplayer { constructor(name, age, height,year) { super(name,age,height) this.year = year } show() { console.log(`我是${this.name},是${this.year}的球员`) } } var p1 = new MVP("库里", "30", "191","2018") p1.show(); //我是库里,是2018的球员复制代码
类的静态方法 static
直接通过类名来访问的方法就是静态方法。如:Math.abs();这里的 abs()是静态方法。 Array.isArray();isArray()是静态方法, 在方法名前加 static 就可以了。这个就不多说了。
总结
关于es6的新增特性呢,还有很多,这里就不一一列举了,,搜索一下,阮一峰,哈哈。