ECMAScript 脚本程序设计语言 欧洲计算机制造商协会,European Computer Manufacturers Association
let变量声明以及声明特性
-
变量不能重复声明
-
块级作用域 全局,函数,eval
-
不存在变量提升
console.log(song); var song = 'aaa';// undefined let song = 'aaa' // 报错
-
不影响作用域链
const声明常量以及特点
声明常量
-
一定要赋初始值
-
一般常量使用大写(潜规则)
-
常量的值不能修改
-
块级作用域
{ const player = 'ABCDEFG' } console.log(player)
-
对于数组和对象的元素修改,不算对常量的修改,不会报错
变量的解构赋值
ES6允许按照一定的模式从数组和对象中提取值,对变量进行赋值
-
数组的解构
const a = ['a', 'b', 'c', 'd']; let [e, f, g, h] = a; console.log(e);//a console.log(f);//b console.log(g);//c console.log(h);//d
-
对象的解构
防止方法重复调用
const zhang = { name: '张', age: '22', like: function() { console.log('emmmmmm....'); } }; // let { // name, // age, // like // } = zhang; // console.log(name); // console.log(age); // console.log(like); // like(); let { like } = zhang; like();
模板字符串 ``
变量拼接
简化对象写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
let name = 'aaa';
let change = function() {
console.log('bbb');
}
const ccc = {
name,
change,
improve: function() {
console.log('ddd');
}
}
console.log(ccc);
箭头函数
let fn = function() {
}
let fn = (a, b) => {
return a + b;
}
let res = fn(1, 2);
console.log(res);
-
this 是静态的,this始终指向函数声明时所在作用域下的this的值
function getName() { console.log(this.name); } let getName2 = () => { console.log(this.name); } window.name = '舒克' const school = { name: 'shuK' }; // getName(); //舒克 // getName2(); //舒克 getName.call(school); //舒克 getName2.call(school); //shuK
-
不能作为构造实例化对象
let Person = (name, age) => { this.name = name; this.age = age; } let me = new Person('xiao', 30); console.log(me); // ERROR
-
不能使用arguments 变量
-
箭头函数的简写
- 省略小括号,当形参有且只有一个的时候
- 省略花括号,当代码体只有一条语句的时候,此时return必须省略
总结:箭头函数适合与this无关 的 回调 => 定时器、数组的方法回调
箭头函数不适合与this有关 的 回调 => 事件回调、对象的方法 ( 只是不适合不是不可以 )
ES6 允许给函数赋初始值
- 形参初始值 具有默认值的参数,一般位置靠后(潜规则)
- 与解构赋值结合
ES6 rest参数
ES6引用 rest参数,用于获取函数的实参,用来代替 arguments ======== 形参
ES5 是 arguments
rest参数必须要放在参数最后function fn(a,b,...args){}
ES6 扩展运算符
[...]
扩展运算符能将 数组 转换为逗号分隔的 参数序列 ========= 函数调用的实参里
- 数组 的 合并
const kz = ['a', 'b'];
const fh = ['c', 'd'];
const zh = [...kz, ...fh];
console.log(zh);
- 数组的克隆
- 将伪数组转换为真正的数组
Symbol
基本使用
是一种类似于字符串的数据类型。
Symbol特点
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol值不能与其他数据进行运算、对比
- Symbol 定义的对象属性不能使用for…in 循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
//symbol
let s1 = Symbol('张书珂');
let s2 = Symbol('张书珂');
console.log(s1 === s2); //false
//函数对象
let s3 = Symbol.for('舒克');
let s4 = Symbol.for('舒克');
console.log(s3 === s4); //true
// 数据类型
// USONB you. are,so,niubility
// u undefined
// s string symbol
// o object
// n nu11 number
// b boolean
Symbol表示独一无二的值,给对象添加属性和方法
let game = {
name: "俄罗斯方块",
up: function() {},
down: function() {}
};
//声明一个对象
let methods = {
up: Symbol(),
down: Symbol()
};
game[methods.up] = function() {
console.log("我可以改变形状");
}
game[methods.down] = function() {
console.log("我可以快速下降!!");
}
console.log(game);
let youxi = {
name: "狼人杀",
[Symbol('say')]: function() {
console.log("我可以发言")
},
[Symbol('zibao')]: function() {
console.log('我可以自爆');
},
}
console.log(youxi)
symbol的内置属性
有很多方法类
hasInstance 自己控制类型检测
class Person {
static[Symbol.hasInstance](param) {
console.log(param);
console.log('aaaaa');
return true;
}
}
let o = {};
console.log(o instanceof Person);
迭代器–自定义遍历数据
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。
任何数据结构只要部署Iterator接口,就可以完成遍历操作。
- ES6 创造了一种新的遍历命令for…of循环. lterator 接口主娶供for…of消费
- 原生具备 iterator接口的数据(可用for of遍历)
a) Array for…in 键名0,1,2,3 for…of 键值
b) Arguments
c) Set
d) Map
e) String
f) TypedArray
g) NodeList
- 工作原理
a) 创建一个指针对象, 指向当前数据结构的起始位置
b) 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
c) 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
d) 每调用next方法返回一个包含value和done属性的对象
注:需要自定义遍历数据的时候,要想到迭代器。
const a = ['a', 'b', 'c'];
let iterator = a[Symbol.iterator]();
for (let i in a) {
console.log(i);//0 1 2
}
for (let i of a) {
console.log(i);//a b c
}
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
//{value: 'a', done: false}
//{value: 'b', done: false}
//{value: 'c', done: false}
//{value: undefined, done: true}
自定义遍历数据
const sk = {
name: 'shuke',
stus: [
'401',
'404',
'505',
'error'
],
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.stus.length) {
const result = {
value: this.stus[index],
done: false
};
index++;
return result;
} else {
return {
value: undefined,
done: true
}
}
}
}
}
}
for (let i of sk) {
console.log(i);
}
生成器–一个特殊的函数
异步编程纯回调函数 node fs ajax mongodb
yield 函数代码的分隔符 线程暂时挂起
函数声明与调用
function* tiger() {
yield '一只没有眼睛';
yield '一只没有尾巴';
yield '真奇怪';
}
const iterator = tiger();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
for (let i of tiger()) {
console.log(i);
}
函数的参数传递
- 整体的函数传参
- next方法可以传参 参数作为上一个yield语句的返回结果
函数实例
解决回调地狱
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
}, 3000)
}, 2000)
}, 1000)
function one() {
setTimeout(() => {
console.log(111);
iterator.next();
}, 1000)
}
function two() {
setTimeout(() => {
console.log(222);
iterator.next();
}, 2000)
}
function three() {
setTimeout(() => {
console.log(333);
iterator.next();
}, 3000)
}
function* gen() {
yield one();
yield two();
yield three();
}
let iterator = gen();
iterator.next();
生成器:异步运行 同步获取
promise
Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,
用来封装异步操作并可以获取其成功或失败的结果。
- Promise 构造函数: Promise (excutor) {}
- Promise.prototype.then 方法
- Promise.prototype.catch 方法
promise封装:
const p = new Promise((resolve, reject) => {
// 创建对象
const xhr = new XMLHttpRequest();
// 初始化
xhr.open("GET", "https://api")
// 发送
xhr.send();
// 绑定事件,处理响应结果
xhr.onreadystatechange = function() {
// 判断
if (xhr.readyState === 4) {
// 判断响应状态码 200-299
if (xhr.status >= 200 && xhr.status < 300) {
// 表示成功
resolve(xhr.response);
} else {
// 如果失败
reject(xhr.status)
}
}
}
});
// 调用then方法
const result = p.then(function(value) {
console.log(value);
}, function(reason) {
console.error(reason);
})
链式:
const p = new Promise((resolve, reject) => {});
const result =
p.then(value=>{
}, reason=>{
}).then(value=>{}, reason=>{})
详细的再看别的视频
Set
集合实践:
//Set
let arr = [1, 2, 4, 2, 5, 6];
let arr2 = [2, 4, 2, 6, 3];
// 数组去重
let result = [...new Set(arr)];
let result2 = [...new Set(arr2)];
console.log(result);
console.log(result2);
// 交集
let result3 = [...new Set(arr)].filter(item => new Set(arr2).has(item));
console.log(result3);
// 并集
let union = [...new Set([...arr, ...arr2])];
console.log(union);
// 差集
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
console.log(diff);
Map
ES6提供了Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator 接口,所以可以使用【扩展运算符】和【for…of…】进行遍历。Map的属性和方法:
- size 返回Map的元素个数
- set 增加一个新元素,返回当前Map
- get 返回键名对象的键值
- has 检测Map中是否包含某个元素,返回boolean值
- clear 清空集合,返回undefined
//Map
let m = new Map();
//添加元素
m.set('123', '123');
m.set('12', function() {
console.log('12');
});
let key = {
name: '12345'
};
m.set(key, ['1', '2', '3', '4', '5']);
//大小
console.log(m.size);
//删除
m.delete('123');
//获取
console.log(m.get('12'));
console.log(m.get(key));
//清空
m.clear();
for (let v of m) {
console.log(v);
}
console.log(m);
Class
// 普通方法
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function() {
console.log('123');
}
let HW = new Phone('1+', '1234');
HW.call();
console.log(HW);
// class
class shouji {
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
call() {
console.log('123');
}
}
let onePlus = new shouji('1+', '1234');
console.log(onePlus);
// 实例对象和函数对象是不相通的
// 实例对象:nokia
// 函数对象:Phone
function Phone() {}
Phone.name = '手机';
Phone.change = function() {
console.log("我可以改变世界");
}
Phone.prototype.size = '5.5inch';
let nokia = new Phone();
console.log(nokia.name);//undefined
// nokia.change( );
console.log(nokia.size);//5.5inch
对于static标注的属性和方法 属于类 不属于实例对象
class Phone {
//静态属性
static name = '手机';
static change() {
console.log("我可以改变世界");
}
}
let nokia = new Phone();
console.log(nokia.name);
console.log(Phone.name);
构造函数的继承
//手机
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function() {
console.log("我可以打电话");
}
//智能手机
function SmartPhone(brand, price, color, size) {
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
//设置子级构造函数的原型
SmartPhone.prototype = new Phone;
SmartPhone.prototype.constructor = SmartPhone;
//声明子类的方法
SmartPhone.prototype.photo = function() {
console.log("我可以拍照")
}
SmartPhone.prototype.playGame = function() {
console.log("我可以玩游戏");
}
const chuizi = new SmartPhone('锤子', 2499, '黑色', '5.5inch');
console.log(chuizi);
class的类继承
class Phone {
//构造方法
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 父类的成员属性
call() {
console.log('我可以打电话');
}
}
class SmartPhone extends Phone {
// 构造方法
constructor(brand, price, color, size) {
super(brand, price);
this.color = color;
this.size = size;
}
photo() {
console.log('拍照');
}
playGame() {
console.log('玩游戏');
}
}
let xiaomi = new SmartPhone('xiaomi', 2800, 'black', '6inch');
console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
JS class 方法中:子类不可以直接去调用父类中同名的方法
class Phone {
//构造方法
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 父类的成员属性
call() {
console.log('我可以打电话');
}
}
class SmartPhone extends Phone {
// 构造方法
constructor(brand, price, color, size) {
super(brand, price);
this.color = color;
this.size = size;
}
call() {
console.log('我可以进行视频通话');
}
}
let xiaomi = new SmartPhone('xiaomi', 2800, 'black', '6inch');
console.log(xiaomi);
xiaomi.call();
class中的getter和setter
//get set
class Phone {
get price() {
console.log('123');
return '12345';
}
// set 方法需要带上一个参数
set price(newVal) {
console.log('1234');
}
}
// 实例化对象
let s = new Phone();
console.log(s.price);// 123 12345
s.price = 'free';//1234