ES6学习笔记
变量
let
- let 变量不能重复声明
- let 作用域为块级作用域
- let 不存在变量提升
- let 不影响作用域链
const
- 使用const 一定要赋初值
- 一般常量使用大写
- 常量的值不能修改
- 块级作用域
- 对于数组和对象的元素修改,不算做对常量的修改,不会报错
解构对象赋值
- ES6 允许按照一定模式从哪个数组的对象中提取值,对变量进行赋值,这被称为解构赋值
- 数组与对象的解构赋值稍有不同
- 数组的解构赋值:
const F4 = [18, 'B', 'C', 'D'];
let [c, d] = F4;
console.log(c);
console.log(d);
- 对象的解构赋值:
const zhao = {
name: '赵本山',
age: 19,
play: function() {
console.log('我在演小品');
}
let {
age
} = zhao;
console.log(age);
模板字符串
- ES6 引入新的声明字符串的方式,使用反引号``
- 内容中可以直接出现换行
- 反引号中的变量使用 ${变量名} 的方式进行拼接
let str = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`;
console.log(str);
let star = `小李`;
let love = `我最喜欢的明星是${star}`;
console.log(love);
对象的简化方法
- ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
- 具体用例:
let name = '霍格沃兹';
let change = function() {
console.log('让我们来改变你');
}
let school1 = {
name1: name,
change1: change,
improve1: function() {
console.log('让我们继续提升吧');
}
}
school1.change1();
console.log(school1.name1);
school1.improve1();
let school2 = {
name,
change,
improve2() {
console.log('让我们共同提升吧');
}
}
school2.change();
console.log(school2.name);
school2.improve2();
箭头函数
函数声明
function add1(a, b) {
return a + b;
}
console.log(add1(3, 4));
let add2 = (a, b) => {
return a + b;
}
console.log(add2(
箭头函数的this
- 普通函数this 指向调用者
- 箭头函数始终指向函数声明时所在作用域下的this 值
- 或者说,箭头函数没有自己的 this 只能用外层的 this
function getName() {
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
}
window.name = '哈利波特'
const school = {
name: '格兰芬多',
}
getName();
getName2();
getName.call(school);
getName2.call(school);
箭头函数的简写
- 当形参有且只有一个的时候,可以省略小括号
- 当代码体只有一条语句是,此时return 必须省略,并且语句的实行结果 就是 函数的返回值
let double = n => n * n;
let result = double(13);
console.log(result);
箭头函数适用之处
- 箭头函数适用于与 this 无关的回调,比如说 定时器 数组 的方法回调
- 箭头函数不适合与 this 有关的回调,比如说 事件回调 对象的方法
- 具体用例:
let change = document.querySelectorAll('.change');
change[0].addEventListener('click', function() {
let _this = this;
setInterval(function() {
_this.style.backgroundColor = 'pink';
}, 2000);
});
change[1].addEventListener('click', function() {
console.log(this);
setInterval(() => {
this.style.backgroundColor = 'pink';
}, 2000)
});
let arr = [1, 6, 0, 100, 200, 4];
let array = arr.filter(function(item) {
return item % 2 === 0;
});
console.log(array);
let array2 = arr.filter(item => item % 2 === 0);
console.log(array2);
注意
- 箭头函数不能作为构造实例化对象
- 箭头函数不能使用 arguments 变量
函数形参赋初值
- ES6 允许给函数形参赋初值
- 形参初始值 具有默认的数值,一般位置靠后
- 具体用例:
let add = (a, b, c = 10) => a + b + c;
console.log(add(3, 5));
- 形参赋初值可以与解构赋值结合使用
- 具体用例:
let connect = ({
host = `127.0.0.1`,
username,
password,
port
}) => {
console.log(host);
console.log(username);
console.log(password);
console.log(port);
}
connect({
username: `root`,
password: `root`,
port: 8000,
});
rest
- ES6 引入rest 参数,来代替 arguments
- 注意:rest 参数必须放到最后
- 具体用例:
let show = (...args) => {
console.log(args);
};
show(1, 2, 3, 9);
let show2 = (a, b, c, ...args) => {
console.log(a);
console.log(b);
console.log(c);
console.log(args);
};
show2(5, 6, 3, 1, 8, 33, 44);
扩展运算符 【…】
- 扩展运算符【…】能将【数组】转换为逗号分隔的【参数序列】
- 具体用例:
const driver = [`周杰伦`, `陈冠希`, `谢霆锋`];
let drive = (...agrs) => {
console.log(agrs);
};
drive(...driver);
drive(`周杰伦`, `陈冠希`, `谢霆锋`);
const kuaizi = [3, `肖央`];
const fenghuang = [`曾毅`, `玲花`];
const together = kuaizi.concat(fenghuang);
console.log(together);
const together2 = [...kuaizi, ...fenghuang];
console.log(together2);
const bingo = [`b`, `i`, `n`, `g`, `o`];
const Bingo = [...bingo];
console.log(Bingo);
const divs = document.querySelectorAll('div');
console.log(divs);
let divArr = [...divs];
console.log(divArr);
Symbol
- Symbol 表示独一无二的值,值是唯一的,用来解决命名冲突的问题
- Symbol 的值不能与其他数据进行运算(比较 也算是一种运算),但可以进行赋值
- Symbol 定义的对象那个属性不能使用 for…in 循环遍历,但可以使用Reflect.ownKeys 来获取对象的所有键名
Symbol的创建
函数创建 Symbol()
- 用函数创建的即使括号里面的值相同,两个Symbol 数据都是不相同的
let s = Symbol('上限乌达');
let s1 = Symbol('上限乌达');
console.log(s === s1);
对象方法创建 Symbol.for()
- Symbol.for() 方法会根据给定的值,从运行时的Symbol 注册表中查找对应的Symbol 值
- 找到了则返回
- 找不到就创建一个
- 或者说,对象是引用类型,引用的地址相同
let s3 = Symbol.for('天动万象');
let s4 = Symbol.for(4);
s3 = s4;
console.log(s3)
Symbol 的使用
let game = {
name: `俄罗斯方块`,
up: () => {
console.log(`upupup`);
},
down: () => {
console.log(`downdowndown`);
},
[Symbol.for(`up`)]: () => {
console.log('累了毁灭吧');
},
[Symbol.for(`天堂之门`)]: () => {
console.log(`黑蚊子多`);
},
[Symbol.for(`天堂之门`)]: () => {
console.log(`搭嘎 口头哇路`);
},
[Symbol(`世界`)]: () => {
console.log(`砸瓦鲁多`);
},
}
let method = {
up: Symbol(`up`),
down: Symbol(`down`)
}
game[method.up] = () => {
console.log(`上升吧少年`);
}
game[method.down] = () => {
console.log(`震颤吧世界`);
}
console.log(game);
game[method.up]();
game[method.down]();
game[Symbol.for(`天堂之门`)]();
game[Object.getOwnPropertySymbols(game)[0]]();
Symbol 的内置属性
- Symbol 的内置属性有很多,Symbol.内置属性 作为其他对象的属性进行使用
迭代器
迭代器的基本理解
- 迭代器(iterator)是一种接口,为不同的数据结构提供统一的访问机制
- 任何数据结构只要部署了 iterator 接口,就可以完成遍历操作
- ES6 中iterator 主要供 for…of 消费
- for…in 保存的是键值 for…of 保存的是键名
- 原生具备iterator 接口的数据(可用for…of 遍历)
- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
- 工作原理:
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next 方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next 方法,指针一直往后移动,直到指向最后一个成员
- 每调用next 方法返回一个包含value 和done 属性的对象
- 注意:需要自定义遍历数据的时候,要想到迭代器
面向过程编程 POP
- 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用即可
- 优点:性能比面向对象高,适合跟硬件联系很紧密的东西,例如单片机
- 缺点:没有面向对象易维护、易复用、易扩展
面向对象编程 OOP
- 面向对象是把事务分解成一个个对象,然后由对象之间分工合作
- 面向对象是以对象功能来划分问题,而不是步骤
- 在面向对象程序开发思想中,每一个对象都是功能中心,具有明确分工
- 面向对象的特性:
- 优点:易维护、易复用、易扩展。由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更灵活,更加易于维护,更适合于多人合作开发的大型软件项目
- 缺点:性能比面向过程低
ES6 中的类和对象
- 面向对象的思维特点:
- 抽取(抽象)对象共有的属性和行为组织(封装)成一个类(模板)
- 对类进行实例化,获取类的对象
- 对象:在JavaScript中对象是一组无序的相关属性和方法的集合,所有的事物都是对象
- 类:
- 在ES6 中新增了类的概念,可以使用class 关键字声明一个类,之后以这个类来实例化对象
- 类抽取了对象的公共部分,它泛指一大类(class)
- 对象特指某一个,通过类实例化一个具体的对象
创建类
语法:
- 通过class 关键字创建类,类名习惯性大写
claee Name {
}
const xx = new name();
类 constructor 构造函数
- constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new 命令生成对象实例时,自动调用该方法。如果没有显示定义,类内部会自动给我们创建一个constructor()
注意
- 创建类 类名后面不要加小括号
- 生成实例 类名后面加小括号
- 创建类里面 所有的函数不需要加function
- 类 里面多个函数 或者方法 之间不可以加逗号
具体用例
class Dalao {
constructor(uname, age) {
this.uname = uname;
this.age = age;
}
sing(skill) {
console.log(`${this.uname}会搞${skill}`);
}
}
const hsj = new Dalao(`黄思杰`, 18);
const whb = new Dalao(`吴浩斌`, 17);
console.log(hsj);
console.log(whb);
hsj.sing(`前端`);
whb.sing(`后端`);
类的继承
extend
- 语法:
class Father{
}
class Son extend Father{
}
super
- super 关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数。super()默认调用父类的构造函数
- super.方法名(); 可用于调用父类的方法
- 子类在构造函数中使用super,必须放到this 前面(必须先调用父类的构造方法,再使用子类构造方法)
具体用例
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor(x, y) {
super(x, y);
this.x = x;
this.y = y;
}
substract() {
console.log(this.x - this.y);
}
}
const son1 = new Son(10, 11);
son1.sum();
son1.substract();
注意
- 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
- 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法
- 也就是 就近原则
class Father {
say() {
return (`我是爸爸`);
}
}
class Son extends Father {
say() {
console.log(`我是儿子`);
console.log(`${super.say()}的儿子`);
}
}
const son = new Son();
son.say();
注意
- 在ES6 中没有变量提升,所以必须先定义类,才能通过类实例化对象
- 类里面的共有属性和方法一定要加this 使用
- 类里面的this 指向问题 箭头函数里面的this 普通函数里面的this
- constructor 里面的this 指向实例对象,方法里面的this 指向这个方法的调用者
promise
- 异步编程解决方案,是一个构造函数,用来封装异步操作并可以获取其陈宫或失败的结果
- 基本用法:
const p=new Promise(function(resolve,reject){
let data="数据";
resolve(data);
});
p.then(function(value){
console.log(value)
},function(reason){
console.error(reason)
});