由于最近学习Vue,它的语法规范大部分使用的ES6的语法,所以来补充补充ES6知识吧,另外现在很多流行的框架都是基于ES6语法开发的,可知ES6的语法重要性。
废话不多说,知识点走起!
变量(let)与常量定义(const)
let的定义和使用
var b =3;
{
//b =3 //ReferenceError: b is not defined 暂时性死区
let b;
b=4
console.log(b) // 它的结果是4,
}
console.log(b) // 它的结果是3
什么是暂时性死区?
在一个块级作用域中,使用let/const声明变量时,只要变量还没有声明完成前就使用,就会报错,这就时暂时性死区。
暂时性死区的作用?
它主要是为了减少运行时错误,防止在声明变量未完成之前使用。
let不允许重复声明
function check(){
let a = 0
var a =0
console.log(a)
}
check() // 报错
//let不允许在相同作用域内,重复声明同一个变量。
ES6 明确规定,如果区块中存在let 和 const 命令,这个区块对这些命令声明
的变量,从一开始就形成了封闭作用域,凡是在声明之前就使用这些变量就会报错。
### const定义和使用
const Arr = 2;
console.log(Arr);
// Arr = 3 它会报错,常量不可以更改值,常量在定义并且赋值后,就不可以在修改值了
const Array = [1,3,4];
console.log(Array)
Array[3] = 333;
console.log(Array) // [1, 3, 4, 333]
//Array = [22,55,88]; 它会报错, 变量本身不可以更改,但可以通过索引或这数组方法来改变元素的值
Array.push(555);
console.log(Array) //[1, 3, 4, 333, 555]
## 变量和对象解构赋值
### 解构分类:
1.数组解构
2.对象解构
3.字符串解构
4.函数参数解构
什么是解构赋值?
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
// 字符串解构-----------字符串会被转换成一个类型数组的对象,每个对象都有length属性
let {length:len} = 'sayHello'
console.log(len)// 会输出sayHello的长度 8
// 数组赋值
let [a,b,c] = [1,2,3]
console.log(a,b,c) // 1 2 3
console.log("------------另一种用法--------------")
let [d,e,...other] = [1,2,3,4,5,6]
console.log(d,e,other)// other是1,2后面的数,他们组成一个新的数组 1 2 [ 3,4 5 6]
//对象赋值----------常用于函数传参
let {name,age} = {name:"张三",age:20}
console.log(name,age) //张三 20
// 函数赋值
function check(){
return [100,200]
}
let [A,B] = check();
console.log(A,B) // 100 200
//函数参数名指定
function fun({x=1,y=2}){
return x-y;
}
console.log(fun({}))//-1 函数不传参数时,它会指定默认值进行计算
console.log(fun({x:22}))//20 解构函数传参不限制传参个数
console.log(fun({x:22,y:88}))//-66
let [ x = 1,bn=4] = [undefined,888] //默认值生效:只要将等会右边对应的设置为undefinded,就会生效
console.log(x+"-------"+bn) // 1 888
解构赋值用途?
1. 交换变量的值
2. 交换变量的值(将它们放在数组或对象里返回)
3. 函数参数的定义
4. 提取 JSON 数据
5. 函数参数的默认值
6. 遍历 Map 结构
进制的转化
0b---------二进制
0o---------十进制
0x----------十六进制
console.log('10的二进制'+0b10)
console.log('10的十进制'+0o10)
console.log('10的十六进制'+0x10)
let num = 20;
console.log(num.toString(8))// 将num转换成8进制
console.log(num.toString(14))// 将num转换成14进制
// 变量数值.toString(数字)-----------数字是指定多少进制的
字符串模板
let name = '小红';
console.log(`我是${name}`) // 字符串中嵌入变量使用
let str = `你的?爱好是啥了? // 多行输出
打?
`
console.log(str)//你的?爱好是啥了?
//打?
扩展运算符(...)
function long(...arg){
console.log(arg)
}
long(1,2,3,4,5,6)
// 可变长参数定义格式: 在函数参数部分 (...参数)
//它可以给函数参数传递多个参数,也可以传递一个值
扩展运算符的应用
1.复制数组
// 以下是错误的复制数组,它只是执向同一份数据的另一个指针,修改a2,a1的值就会发生改变
const a1 = [1, 2];
const a2 = a1;
a2[0] = 2;
a1 // [2, 2]
// 正确的克隆复制数组
// 写法一
//const a2 = [...a1];
// 写法二
const [...a2] = a1;
a2[0] = 22;
console.log(a1) //[1, 2]
console.log(a2) //[22, 2]
2.合并数组
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
## 箭头函数
箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种只包含一个表达式,连{ ... }和return都省略掉了。
还有一种可以包含多条语句,这时候就不能省略{ ... }和return:
使用格式
(参数1, 参数2, …, 参数N) => { 函数声明 }
(参数1, 参数2, …, 参数N) => 表达式(单一)
//相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }
// 当只有一个参数时,圆括号是可选的:
(单一参数) => {函数声明}
单一参数 => {函数声明}
// 没有参数的函数应该写成一对圆括号。
() => {函数声明}
//加括号的函数体返回对象字面表达式:
参数=> ({foo: bar})
//支持剩余参数和默认参数
(参数1, 参数2, ...rest) => {函数声明}
(参数1 = 默认值1,参数2, …, 参数N = 默认值N) => {函数声明}
//同样支持参数列表解构
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f(); // 6
// 两个参数
var add = (x,y) =>{
return x+y
}
console.log(add(6,8)) // 14
//没有参数
var check = ()=>'没有参数'
console.log(check()) // 没有参数
//可变参数
var change = (a,b, ...c) =>{
c.forEach(function(val){
console.log(val)
})
}
change(5,5,6,8,10,55) // 6,8,10,55
//箭头函数也可以使用三元运算符
var arr = [ 9,8,4,2,11]
var s = arr.filter(newArr => newArr%2==0?newArr:0)
console.log(s)
// 箭头函数也可以使用闭包:
var Add = (i=0) => {return (() => (++i) )};
var v = Add();
v(); //1
v(); //2
//因为仅有一个返回,return 及括号()也可以省略
var Add = (i=0)=> ()=> (++i);
箭头函数的作用:
更简短的函数并且不绑定this,并且没有自己的this,arguments,super或 new.target。这些函数表达式更适用于那些本来需要匿名函数的地方,并且它们不能用作构造函数。
---
箭头函数使用注意:
1.箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。
有关this使用的说明
- 箭头函数没有自己的this指针,通过 call() 或 apply() 方法调用一个函数时,只能传递参数(不能绑定this---译者注),他们的第一个参数会被忽略。
var adder = {
base : 1,
add : function(a) {
var f = v => v + this.base;
return f(a);
},
addThruCall: function(a) {
var f = v => v + this.base;
var b = {
base : 2
};
return f.call(b, a);
}
};
console.log(adder.add(1)); // 输出 2
console.log(adder.addThruCall(1)); // 仍然输出 2(而不是3 ——译者注)
3.箭头函数不能用作构造器,和 new一起用会抛出错误。
4.箭头函数没有prototype属性。
Symbol
什么是Symbol?:
symbol 是一种基本数据类型,
该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的symbol注册
每个从Symbol()返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据类型仅有的目的
Symbol格式:
Symbol([description])
参数:可选的字符串。symbol的描述,可用于调试但不能访问symbol本身
// Symbol 作为常量
const Java = Symbol();
let a = Java;
if(a === Java){ //true
console.log("a 和 java相等")
}
// Symbol作为属性
let s1 = Symbol('aa')
let s2 = Symbol('AK47')
// s1 s2 作为对象属性的标记来使用
var arr = {}
arr[s1]="nihao"
arr[s2]="Hello"
console.log(arr)
console.log(arr[s1])
console.log(arr[s2])
// 半隐藏属性:特点:知道的人可以使用,不知道的不能使用
const My = Symbol();
class User{
constructor(name,age,key){
this[My] = key;
this.name = name;
this.age = age;
}
CheckKey(key) {
return this[My] === key;
}
}
let user = new User("老王",20,3333)
// 知道有user[My] 属性才可以使用,不知道不能使用, 通过输出对象,就能知道是否有定义的Symbol半隐藏属性】
console.log(user.name+"----"+user.age+"-----"+user[My]);
//Object.keys()----会返回一个对象的属性数组
//它不会返回半隐藏属性,因为隐藏了
console.log(Object.keys(user))
//输出对象,可以得知对象的所有属性
console.log(user)
console.log(user.CheckKey(222))
*
Symbol主要用来作为对象属性的标识符
*
for-of和for-in的区别
在ES6之前,迭代元素都使用for-in去遍历,但是它有一个缺点,就是当你遍历数组时,你只想获取数组的值,它会遍历跟数组
相关的一切属性(除了Array的length属性却不包括在内)!
ES6的出现,for-of大大解决了这一缺点,它只会获取数组的值。
ES6之前
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
console.log(x); // '0', '1', '2', 'name'
}
//2.for ... of循环则完全修复了这些问题,它只循环集合本身的元素:
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a) {
console.log(x); // 'A', 'B', 'C'
}
类定义
// 不能用类实例化对象,通过 类.方法 就可以访问该方法
class Car{
constructor(name,price){------------构造器
this.name=name;
this.price=price;
}
run(){
console.log(`${this.name}车的价格为${this.price}`)
}
static action(){---------------------静态方法
// let force = (this.price>100000&this.price<150000)?
// '该车的动力功能一般':'该车的动力功能可以';
// console.log(force)
if(`${this.price}`<100000){
console.log('该车的动力功能一般')
}else{
console.log('该车的动力功能可以')
}
}
}
let sedan = new Car('捷达-263',2000);
console.log(sedan.name,sedan.price);
console.log(sedan);
//sedan.action();--------会报错,类实例化对象不可以访问静态方法
sedan.run();
Car.action();
setter和getter
// setter/getter 功能相当于----------java中(set和get)设置方法中内容 取得方法中内容
class People{
constructor(name){
this.name=name
}
get age(){
return this._age;
}
set age(val){
this._age=val;
}
show(){
console.log(`名字:${this.name},年龄:${this.age}`)
}
}
let A = new People('People');
console.log(A)
A.age=22;
console.log(A.age)
console.log(A)
## 类继承
其实JavaScript 和 Java 创建类,继承挺相似的!
class Animal{
constructor(name){
this.name = name;
}
show(){
console.log(`该动物是${this.name}`)
}
}
class Dog extends Animal{
constructor(name,trait){
super(name)
this.trait=trait;
}
type(){
switch(this.trait){
case '吃肉':
return '食肉动物'
case '吃素':
return '食草动物'
default:
throw new Error('没有该类型动物')
}
}
}
let dog = new Dog('哈士奇','吃肉');
dog.show();
console.log(dog.type())
Set与Map
什么是Set?
ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。
//Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
var mySet = new Set();
mySet.add(1);
mySet.add("foo");
var a = new Set([11,22,33,44,55]);
console.log([...a]) //11,22,33,44,55
Set 四个方法
add(value):添加某个值,返回Set结构本身
delete(value):删除某个值,返回一个布尔值,表示删除是否成功
has(value):返回一个布尔值,表示该值是否为Set的成员
clear():清除所有成员,没有返回值
mySet.size; // 2
mySet.has("foo"); // true
//mySet.clear();
mySet.size; // 0
mySet.has("bar") // false
// 用forEach迭代
mySet.forEach(function(value) {
console.log(value);
});
// Set和Array互换
//第一种方法
mySet2 = new Set([1,2,3,4]);
mySet2.size; // 4
console.log([...mySet2])
//第二种方法
var myArray = ["value1", "value2", "value3"];
// 用Set构造器将Array转换为Set
var mySet = new Set(myArray);
mySet.has("value1"); // returns true
// 用...(展开操作符)操作符将Set转换为Array
console.log([...mySet]); // 与myArray完全一致
//Set对象去重
console.log([...new Set([1,1,2,3,5,88,999,22,88,88,88,1111])])
Set 结构有四个遍历方法:
1.keys()返回键名的遍历器
2.values()返回键值的遍历器
3.entries()返回键值对的遍历器
4.forEach()使用回调函数遍历每个成员
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.values()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.entries()) {
console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
什么是Map?
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
//Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
let map = new Map();
map.set('name','张三') // 通过set 添加键值对
map.set('age',22)
// 一些Map常用方法
console.log(map.size)//-----------map的大小
console.log(map.has("name"))//------------------map对象是否包含name
//map.clear()//-----------------------清空map对象
console.log(map.size) //0
Map结构有四个遍历方法:
1.keys()返回键名的遍历器
2.values()返回键值的遍历器
3.entries()返回键值对的遍历器
以上3个方法都是通过 for(let of )遍历
4.forEach()使用回调函数遍历每个成员
Map结构转数组结构,通过扩展运算符(...)
const map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
[...map.keys()]
// [1, 2, 3]
[...map.values()]
// ['one', 'two', 'three']
[...map.entries()]
// [[1,'one'], [2, 'two'], [3, 'three']]
[...map]
// [[1,'one'], [2, 'two'], [3, 'three']]
Map转化为数组结构后,它就可以使用数组的方法,可以实现更多的方法,例如数组的过滤filter..........
以上是关于ES6的知识点,可能不全,但是最常用的,平常遇到不会的知识点,可以去阮一峰 网站去看ES6,特别不错,讲的特别细。
接下来,补充一下JS高级知识,开始Vue,做项目?