本节所要介绍的是关于 ES6 基础部分的内容 ES6 干货指南 (上)
- ES6 基础语法熟悉的可以侃侃 ES6 进阶部分的内容 ES6 干货指南 (中)
- ES6 整体熟悉了解的可以侃侃 ES6 拓展部分的内容 ES6 干货指南 (下)
一、新增关键字
let
、const
ES6新增的两个声明变量/常量的关键字
- 不能重复声明;
- 不会预编译,无变量提升(即不会有声明提前,但事实上只是人为看到的效果,实际上是有声明提前,提前临时性的死区中)
- 块级作用域,ES6新增了一个作用域 块级作用域,一个"{ }"就是一个块级作用域
- 暂时性死区,一个作用域内未声明则不可使用
- 声明的变量不会挂在window中,不会造成全局变量的污染;
const
不能修改,const
声明和赋值必须一次性完成,并且后期不允许改变存储空间的地址
- 对于想了解let关键字详细使用的伙伴可以去看看这篇文章 ECMAScript6:let 命令操作
二、模板字符串
字符串换行问题
// 以往方式,当字符串长度极长时,出现换行则必须用+连接,并重新用""包裹
let str = "asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl" +
"qwertyuioqwertyuioqwertyuioqwertyuioqwertyuioqwertyuio" +
"zxcvbnmzxcvbnmzxcvbnmzxcvbnmzxcvbnmzxcvbnmzxcvbnm" ;
// 模板字符串只需整体前后``包裹即可
let stri = `asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl
qwertyuioqwertyuioqwertyuioqwertyuioqwertyuioqwertyuio
zxcvbnmzxcvbnmzxcvbnmzxcvbnmzxcvbnmzxcvbnmzxcvbnm` ;
字符串拼接变量
let tmp = "Hello";
let str = tmp + "world"; // 普通拼接方式 + 连接
let stri = `${tmp}world`; // 模板字符串``前后包裹,变量用${}存放即可
三、解构赋值
什么是解构赋值?
let obj = {
name : "Json",
sex : "man",
}
let {name : oName, sex:oSex} = obj; // 这样将对象的属性值反向赋值的操作即是 解构赋值
console.log(oName,oSex); // Json man
结构赋值简单的应用在数组上
let arr = [1,2,3,4,5];
let {4:a,2:b,0:c} = arr;
console.log(a,b,c); // 输出:5 3 1
四、点点点运算符
点点点运算符的主要作用:收集参数,构成一个参数数组(真数组)
function foo(...arg){
console.log(arg); // 这里的arg是真数组 可以调用Array对象的方法
console.log(arguments); // arguments伪数组
}
foo(1,2,3,4,5)
点点点运算符还可直接操作数组
let arr = [1,2,3];
let arr2 = [4,5,6];
console.log(...arr); // 1 2 3
let newArr = [...arr,...arr2];
console.log(newArr); // [1, 2, 3, 4, 5, 6]
在ES7中点点点运算符可以操作对象
let a = {
name :"Json",
age : 24
};
let b = {
name :"Code",
sex : "man"
};
let c = {
...a,
...b
};
console.log(c); // {name: "Code", age: 24, sex: "man"}
五、形参默认值
形参默认值即函数调用时未传实参,则形参使用设置的默认值
function foo(a=0,b=0){
console.log(a,b);
}
foo(1,1); // 1 1
foo(); // 0 0
形参默认值也有暂时性死区
function foo(a=b,b=0){
console.log(a,b);
}
foo(1) // 1 0
foo(); // Cannot access 'b' before initialization
六、箭头函数
箭头函数写法
- 创建一个箭头函数
const foo = (para1,para2) => {
console.log("Hello Wolrd");
}
- 箭头函数参数只有一个,可以省略小括号
const foo = para=> console.log("Hello Wolrd");
- 箭头函数只有一条返回语句,可以省略花括号,可以省略
return
const foo = (para1,para2) => 返回值;
- 如果返回值是一个对象,直接用
{}
返回会被当作成函数体,所以需要将返回值变成表达式的形式可用()
包裹需返回的对象
const foo = (para1,para2) => ({
a : para1,
b : para2
})
箭头函数的 this 问题
// 事实上箭头函数中没有this,如果要强行使用,则指向函数外层对应的 this (箭头函数也没有argument和new.target)
const fun = () => console.log(this); // window
const obj = {
fun: function(){
const foo = () => console.log(this); // {fun: ƒ}
}
}
箭头函数的原型
// 箭头函数没有原型,不能当成构造函数来使用,所以占用空间非常小,
const fun = () => { }
console.log(fun.prototype); // undefined
let obj = new fun(); // fun is not a constructor
箭头函数使用时要注意那些问题?
- 临时使用的函数,并不会刻意的去调用异步的处理函数、事件的处理函数
- 继续去沿用外层的 this
- 对象的属性不要去用箭头函数,除非是特别的需求
- 数组方法的时候,保证代码的简洁
七、class类
类产生的原因?
要探究类产生的原因那么就得看传统的构造函数有那么问题。
- 构造函数下的属性及方法和原型上的属性及方法分离了,代码可读性差
- 构造函数原型上的属性及方法是可以枚举的
- 构造函数也是可以当成普通函数使用的
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
// too many code
}
Person.prototype.foo= function(){
console.log(this.name,this.age,this.sex);
// too many code
}
for(const prop in new Person())
console.log(prop); // name age sex foo
console.log(Person()); // undefined
console.log(new Person()); // Person {name: undefined, age: undefined, sex: undefined}
针对上述三点类做的优化:
- 类的声明不会被提升,和
let
const
一样,有暂时性死区 - 类的所有代码全都是在严格模式中执行
- 类的所有方法都是不可枚举的
- 类的所有方法都无法当成构造函数直接使用
- 类的构造器必须使用
new
来调用
class Person{
constructor(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
// too many code
}
foo(){
console.log(this.name,this.age,this.sex);
}
}
const obj = new Person();
for(const prop in obj )
console.log(prop); // name age sex
const ob = new obj.foo(); // obj.foois not a constructor
const oc = Person(); // Class constructor PersonC cannot be invoked without 'new'
类的静态成员
- 使用
static
声明,添加的是类的静态成员 - 没有使用,则位于对象上
- 箭头函数在类中使用,指向当前对象
class Person{
a = "对象上的属性";
static b = "类的静态属性";
c = 0;
static c = 1;
foo = () => console.log(this.c);
}
console.log(new Person().a); // "对象上的属性"
console.log(Person.b); // "类的静态属性"
new Person().foo(); // 0
类的继承
- 继承:如果存在两个类 A 和 B 且 B 是 A ,则 B 继承自 A,A 派生 B,B 是 A 的子类,A 是 B 的父类
- 类中的继承采用
extends
定义 - 继承中同名的属性及方法会进行覆盖
super
既可以当作函数使用,也可以当作对象使用
直接当成函数调用,表示父类的构造;
当成对象使用,则表示父类的原型;
class Animal{
constructor(type,name){
this.type = type;
this.name = name;
}
foo(){
console.log(this.type,this.name)
}
}
class Dog extends Animal{
// 如果子类定义了constructor,则必须在constructor的第一行手动调用父类的构造函数super()
// 如果子类不写constructor,则会有默认的构造器,自动去调用父类的构造器
constructor(type,name,age){
super(type,name);
this.age = age;
}
foo(){ // 同名方法覆盖
super.foo();
console.log(this.age);
}
}
const obj = new Dog("犬类","柯基",5);
console.log(obj); // Dog {type: "犬类", name: "柯基", age: 5}
obj.foo(); // 犬类 柯基 5
八、Object 扩展方法
Object.is()
作用:基本上和 === 一样,除了以下两种情况
console.log(NaN === NaN); // false
console.log(Object.is(NaN,NaN)) // true
console.log(+0 === -0) // true
console.log(Object.is(+0,-0)) // false
Object.assign()
作用:用于混合对象,带浅克隆 (将后者的内容覆盖到前者)
const tmp= {
a : 123,
b : 456,
}
const bar= {
a : 789,
e : "asdf"
}
Object.assign(tmp,bar);
console.log(tmp); // {a: 789, b: 456, e: "asdf"}
Object.getOwnPropertyNames()
作用:枚举出来对象的属性, 返回一个数组 (枚举的顺序由浏览器厂商自行规定)
const obj = {
a : 1,
b : 2,
c : 3,
0 : 4,
1 : 5,
2 : 6
}
const arr = Object.getOwnPropertyNames(obj)
console.log(arr); // ["0", "1", "2", "a", "b", "c"]
Object.setPrototypeOf()
作用:设置某个对象的隐式原型(一种对象的继承方式)
const tmp= {
a : 1
}
const bar= {
b : 2
}
Object.setPrototypeOf(tmp,bar); // 该方法等价于 tmp.__proto__ = bar
console.log(tmp.__proto__.b); // 2
九、Array 扩展方法
Array.from(arg)
作用:将类数组、可迭代对象,转换成新的数组
<div></div> <div></div> <div></div> <div></div> <div></div>
<script>
const div = document.getElementsByTagName("div");
console.log(Array.from(div)); // (5) [div, div, div, div, div]
</script>
Array.find(callback) & Array.findIndex(callback)
作用:筛选出满足条件的元素 & 筛选出满足条件的元素的下标
const arr = [
{
name : "a",
id : 1
},
{
name : "b",
id : 2
},
{
name : "c",
id : 3
},
]
const result = arr.find(item => item.id == 3); // 筛选出满足条件的元素
const resultIndex = arr.findIndex(item => item.id == 3); // 筛选出满足条件的元素的下标
console.log(result); // {name: "c", id: 3}
console.log(resultIndex); // 2
Array.fill(data)
作用:用指定的数据填充代码
const arr = new Array(5);
arr.fill("code");
console.log(arr); // (5) ["code", "code", "code", "code", "code"]
Array.copyWithin(targt,[start],[end])
作用:在数组内以指定元素为目标进行复制
const arr = [1,2,3,4,5,6];
// 使用该实例方法会修改原数组
arr.copyWithin(2);
console.log(arr); // (6) [1, 2, 1, 2, 3, 4]
arr.copyWithin(2,1);
console.log(arr); // (6) [1, 2, 2, 1, 2, 3]
arr.copyWithin(2,1,3);
console.log(arr); // (6) [1, 2, 2, 2, 2, 3]
~~~~~~~~ 关于ES6 的基础部分先说到这,后续还有ES6进阶部分,干货满满 Bye ~~~~~~~~