简介:
ECMA
European Computer Manufactures Association
欧洲计算机制造商协会,该组织的目标是评估、开发、和认可电信和计算机标准,94年后该组织改名为Ecma国标。
ECMAScript是由Ecma国际通过ECMA-262标准化的脚本程序设计语言
Ecma国际制定了许多标准,而ECMA-262只是其中一个
- 语法简洁 功能丰富
- 框架开发应用
- 前端开发职位要求 Vue React Angular
- 版本变动内容最多,具有里程碑意义
- 加入许多新的语法特性,编程实现更简单高效
- 是前端发展的趋势,就业必备技能
注:从ES6开始,每年发布一个版本,版本号比年份最后一位大1
目录
1、let变量声明以及声明特性:
2、Const
3、变量的解构赋值
4、ES6引入新的声明字符串的方式,模版字符串
5、简化对象写法
6、箭头函数以及声明特点
7、箭头函数的实践与应用场景
8、箭头函数的默认设置
9、rest参数
10、扩展运算符的介绍
编辑 11、扩展运算符的应用
12、Symbol的介绍与创建
js7总数据类型总结:
13、对象添加symbol类型的属性
14、Symbol的内置属性
15、iterator迭代器介绍
16、迭代器应用-自定义遍历数据
17、 Promise介绍与基本使用
18、Promise.prototype.then
19、Promise实践-连续读取多个文件
20、Promise对象catch方法
21、Set集合介绍与API
22、Set集合实践
23、Map的介绍与API
24、Class类的介绍
25、Class静态成员
26、ES5构造函数继承
27、ES6 Class类的继承
28、getter和setter
29、数值扩展
30、对象方法扩展
31、模块化介绍、优势
32、浏览器使用ES6模块化
1、let变量声明以及声明特性:
1、变量不能重复声明
2、块级作用域(全局、函数、eval)
{
let girl = ‘aa’;
}
Console.log(girl;) // Uncaught ReferenceError: girl is not defined
- 不存在变量提升
- 不影响作用域链
2、Const
- 声明常量,一定要赋初始值
- 一般常量使用大写(潜规则)
- 常量的值不能修改
- 块级作用域
- 对于数组和对象的元素修改,不算对常量的修改,不会报错
3、变量的解构赋值
ES允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
//1、数组的解构
const F4 = ['小沈阳', '刘能', '赵四', '宋小宝'];
let [xiao, liu, zhao, song] = F4;
console.log(xiao);
console.log(liu);
console.log(zhao);
console.log(song);
//2、对象的解构
const zhao = {
name: '赵本山',
age: '不详',
xiaopin: function () {
console.log('我可以');
}
}
//相当于声明了三个变量并且赋值
// let { name, age, xiaopin } = zhao;
console.log(name);
console.log(age);
console.log(xiaopin);
// xiaopin();
let {xiaopin} = zhao;
//下面的代码存在大量的重复,这时候可以考虑对象的解构赋值来简化代码
// zhao.xiaopin();
// zhao.xiaopin();
// zhao.xiaopin();
xiaopin();
xiaopin();
xiaopin();
4、ES6引入新的声明字符串的方式,模版字符串
// ES6引入新的声明字符串的方式[``](模版字符串,使用反引号) '' ""
//1、声明
let str = `我是一个字符串`;
console.log(str);
//2、内容中可以直接出现换行符
let str2 = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>艾伦</li>
</ul>`;
//3、变量拼接
let lovest = '魏翔';
let out = `${lovest}是我心目中最搞笑的演员`;
console.log(out);
5、简化对象写法
// ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
//这样书写更加简洁
let name = 'hello'
let change = function() {
console.log('我们可以改变世界');
}
const shchool = {
name,
change,
// improve: function(){
// console.log('我们可以提高你的技能');
// }
improve() {
console.log('我们可以提高你的技能');
}
}
6、箭头函数以及声明特点
/ES6允许使用箭头=> 定义函数
// 声明一个函数
let fn = function () { } //之前写法
let fn2 = (a, b) => {
//代码体
return a + b;
} // 简洁写法
//调用函数
let result = fn2(1, 2);
console.log(result);
//1、this是静态的,this始终指向函数声明时所在的作用域下的this的值
function getName() {
//直接调用,普通函数this指向window
console.log(this.name);
}
let getName2 = () => {
//箭头函数在全局作用域下声明的this指向window
console.log(this.name);
}
// 设置window对象的name属性
window.name = '哈哈';
const school = {
name: "HAHA"
}
//直接调用,普通函数this指向window
// getName();
// getName2();
//call方法调用,是可以改变函数内部this的值的
getName.call(school);//HAHA
getName2.call(school);//哈哈
//2、不能作为构造函数实例化对象
let Person = (name, age) => {
this.name = name;
this.age = age;
}
let me = new Person('xiao', 18)
console.log(me);//demo.html:51 Uncaught TypeError: Person is not a constructor
//3、不能使用arguments变量(我们都知道在函数内部有一个特殊的变量arguments来保存实参)
let fn3 = function () {
console.log(arguments);
}
fn3(1, 2, 3);
let fn3 = () => {
console.log(arguments);
}
fn3(1, 2, 3);
//4、箭头函数的简写
//1)省略小括号,当形参有且只有一个的时候
// let add=(n) => {
// return n + n;
// }
let add = n => {
return n + n;
}
console.log(add(9));
//2)省略花括号,当代码体只有一条语句的时候,此时return必须省略,而且语句的执行结果就是函数的返回值
// let pow = (n) => {
// return n * n;
// }
let pow = (n) => n * n;
console.log(pow(9));
7、箭头函数的实践与应用场景
//需求1:点击div 2s 后颜色变成粉色
//获取元素
let ad = document.getElementById('ad');
//绑定事件
ad.addEventListener('click', function () {
//保存this的值
//把当前函数作用域下的this保存,当前函数作用域下this指向的正是ad
let _this = this;
//定时器
// setTimeout(function() {
// //修改背景色 this
// console.log(this);
// _this.style.background = 'pink';
// //在当前作用域下找不到_this,就会往外层作用域下去找
// }, 2000);
setTimeout(() => {
//修改背景色 此时this指向时间源ad
console.log(this);
this.style.background = 'pink';
}, 2000);
})
//需求2:从数组中返回偶数的元素
const arr = [1,6,9,10,100,25];
const result = arr.filter(function(item) {
if (item % 2 === 0) {
return true;
} else {
return false;
}
});
console.log(result);
const result = arr.filter(item => item % 2 === 0)
//需求2:从数组中返回偶数的元素
const arr = [1, 6, 9, 10, 100, 25];
// const result = arr.filter(function(item) {
// if (item % 2 === 0) {
// return true;
// } else {
// return false;
// }
// });
const result = arr.filter(item => item % 2 === 0)
console.log(result);
// 箭头函数适合与this无关的回调,数组方法的回调
//箭头函数不适合与this有关的回调,事件回调,对象的方法
8、箭头函数的默认设置
//ES6允许给函数参数赋初始值
//1.形参初始值,传了就用没传就用默认值,具有默认值的参数一般位置要靠后
function add(a, b, c = 10) {
return a + b + c;
}
let result = add(1,2);
console.log(result);
//2、与解构赋值结合
// function connect(options) {
// let host = options.host;
// let username = options.username;
// let password = options.password;
// let port = options.port;
// }
function connect({ host, username, password, port }) {
console.log(host + username + password + port);
//localhostroot1234568000
}
connect({
host: 'localhost',
username: 'root',
password: '123456',
port: '8000'
})
9、rest参数
/ ES6引入rest参数,用于获取函数的实参,用来代替arguments
// ES5获取实参的方式
function date() {
console.log(arguments);
}
date('白芷', '阿娇', '思慧')
//rest参数
function date(...args) {
console.log(args);
//可以使用数组特有的方法:filter every map some
}
date('白芷', '阿娇', '思慧')
//rest参数必须放到参数最后
function fn(a, b, ...args) {
console.log(a);
console.log(b);
console.log(args);
}
fn(1, 2, 3, 4, 5, 6);
10、扩展运算符的介绍
/ ES6 ... 扩展运算符能将数组转换为逗号分隔的参数序列
//声明一个数组
const tfboys = ['千禧', '王源', '王俊凯'];
//声明一个函数
function chunwan() {
console.log(arguments);
}
chunwan(tfboys);
chunwan(...tfboys);//chunwan('千禧', '王源', '王俊凯')
//与rest参数的区别:
//...args放在了函数形参的位置
//... 扩展运算符放在了调用的位置,实参里面
11、扩展运算符的应用
/1、数组的合并
const kuaizi = ['王太利', '肖央'];
const fenghuang = ['增益', '玲花'];
// const zuixuanxiaopingguo = kuaizi.concat(fenghuang);
const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
console.log(zuixuanxiaopingguo);//2、数组的克隆
const sanzhihua = ['E', 'G', 'M'];
const sanyecao = [...sanzhihua];//['E','G','M'],如果拷贝的里面有引用类型的元素的话为浅拷贝,如果没有引用类型的元素是直接完全复制出一个新数组
//3、将伪数组转为真数组
const divs = document.querySelectorAll('div');
console.log(divs);
const divArr = [...divs];
console.log(divArr);
12、Symbol的介绍与创建
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值,它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol特点:
- Symbol的值是唯一的,用来解决命名冲突的问题
- Symbol值不能与其他数据进行运算
Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
// 创建Symbol
let s1 = Symbol();
console.log(s1, typeof s1);// Symbol() 'symbol'
//添加标识的symbol
let s2 = Symbol('哈哈'); //Symbol是一个函数,通过调用Symbol()函数来创建symbol
let s2_2 = Symbol('哈哈');
console.log(s2 === s2_2);//false
let s3 = Symbol.for('哈哈');//Symbol是一个对象,通过调用对象的for方法来创建symbol,函数对象
let s4 = Symbol.for('哈哈');
console.log(s3 === s4); // true
//不能与其他数据运算
let result = s + 100;
//不能与其他数据运算
let result = s + 100;
js7总数据类型总结:
- USONB you are so niubility
- u undefined
- s string symbol
- o object
- n null number
- b boolean
13、对象添加symbol类型的属性
//向对象中添加方法 up down
let game = {
name: '俄罗斯方块',
up() { },
down() { }
}
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);
14、Symbol的内置属性
除了定义自己使用的symbol值以外,es6还提供了11个内置的symbol值,指向语言内部使用方法。
Symbol.hasInstance | 当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法 |
Symbol.isConcatSpreadable | 对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开 |
Symbol.unscopables | 该对象指定了使用with关键字时,哪些属性会被with环境排除 |
Symbol.match | 当执行str.match(myObject)时,如果该属性存在会调用它,返回该方法的返回值。 |
Symbol.replace | 当该对象被str.replace(myObject)方法调用时会返回该方法的返回值 |
Symbol.search | 当该对象被str.search(myObject)方法调用时会返回该方法的返回值 |
class Person {
static [Symbol.hasInstance](param) {
console.log(param);
console.log('我被用来检测类型了');
return true;
}
}
let o = {};
console.log(o instanceof Person);// true 此时可以把对象o传递到到static方法,由你来决定下一步操作
const arr = [1, 2, 3];
const arr2 = [4, 5, 6];
arr2[Symbol.isConcatSpreadable] = false;//控制arr2数组中的值是否展开
console.log(arr.concat(arr2));
15、iterator迭代器介绍
迭代器(iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口 就可以完成遍历操作。
- ES6创造了一种新的遍历命令for...of 循环,iterator接口主要提供for...of消费
- 原生具备iterator接口的数据可用for...of 遍历
- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
onst xiyou = ['唐僧', '孙悟空', '猪八戒'];
//使用for ... of 遍历数组
for (let v of xiyou) {
console.log(v);//保存的是键值
}
for (let v in xiyou) {
console.log(v);//保存的是键名
}
const xiyou = ['唐僧', '孙悟空', '猪八戒'];
console.log(xiyou);
16、迭代器应用-自定义遍历数据
const banji = {
name: "终极一班",
students: [
'小明',
'小宁',
'小高',
'小李'
],
[Symbol.iterator]() {
//索引变量
let index = 0;
let _this = this;
return {
next: function () {
if (index < _this.students.length) {
const result = { value: _this.students[index], done: false };
//下标自增
index++;
//返回结果
return result;
} else {
return { value: undefined, done: true }
}
}
};
}
}
//遍历对象
for (const v of banji) {
console.log(v);
}
17、 Promise介绍与基本使用
Promise是ES6引入的异步编程的新解决方案(解决回调地狱的问题)。语法上是一个构造函数,用来封装异步操作并可以获取成功或失败的结果。
- Promise构造函数:Promise(excutor) {}
- Promise.prototype.then
- Promise.prototype.catch
const p = new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', ""); xhr.send(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { resolve(xhr.response); } else { reject(xhr.status); } } } }) //把要处理的逻辑放在p.then之后写,没用Promise之前网络请求和逻辑处理的代码只能写一块,导致代码很乱 p.then(function (value) { }, function (err) { })
18、Promise.prototype.then
const p = new Promise((resolve, reject) => { setTimeout(() => { resolve('用户数据'); // reject('出错了'); }, 1000); }) //调用then方法,then方法的返回结果是Promise对象,对象状态由回调函数的执行结果决定 // 1、如果回调函数中返回的结果是非Promise类型的属性,状态为成功,返回值为对象的成功值 const result = p.then(value => { console.log(value); // return '1'; }, reason => { console.warn(reason); }); console.log(result); // 链式调用,可以避免回调地狱 p.then(value => { }).then(value => { });
19、Promise实践-连续读取多个文件
如果是连续多次异步操作用Promise.then()可以使代码看起来更加简洁,有条理,避免陷入回调地狱
//引入fs模块
const { rejects } = require("assert");
const fs = require("fs");
const { resolve } = require("path");
fs.readFile('', (err, data1) => {
fs.readFile('', (err, data2) => {
fs.readFile('', (err, data3) => {
let result = data1 + data2 + data3;
console.log(result);
});
})
})
//使用Promise 实现
const p = new Promise((resolve, reject) => {
fs.readFile('', (err, data) => {
resolve(data)
})
});
p.then(value => {
return new Promise((resolve, reject) => {
fs.readFile('', (err, data) => {
resolve([value, data])
})
})
}).then(value => {
return Promise((resolve, reject) => {
fs.readFile('', (err, data) => {
value.push(data);
resolve(value)
})
})
}).then(value => {
console.log(value);
20、Promise对象catch方法
p.catch(function (reason) {
});
21、Set集合介绍与API
ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用扩展运算符和for...of进行遍历。
- size 返回集合的元素个数
- add 增加一个新元素,返回当前集合
- delete 删除元素,返回Boolean值
- has 检测集合中是否包含某个元素,返回Boolean值
let s = new Set(['a', 'a', 'b', 'c']); console.log(s);//自动去重 for (const v of s) { console.log(v); }
22、Set集合实践
let arr = [1, 2, 3, 4, 5, 6, 2, 1, 3, 4, 7]; //1.数组去重 let result = new Set(arr);//使用扩展运算符展开 console.log(result); let result = [...new Set(arr)];//使用扩展运算符展开 console.log(result); //2.交集 let arr = [1, 2, 3, 4, 5, 6, 2, 1, 3, 4, 7]; let arr2 = [4,5,6,6,5]; let result = [...new Set(arr)].filter(item => new Set(arr2).has(item)) //3.并集 let arr = [1, 2, 3, 4, 5, 6, 2, 1, 3, 4, 7]; let arr2 = [4, 5, 6, 6, 5]; let union = [...arr, ...arr2]; let result = [...new Set(union)]; //4.差集 let arr = [1, 2, 3, 4, 5, 6, 2, 1, 3, 4, 7]; let arr2 = [4, 5, 6, 6, 5]; let result = [...new Set(arr)].filter(item => !new Set(arr2).has(item))
23、Map的介绍与API
ES6提供了Map数据结构,它类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map也实现的iterator接口,所以也可以使用扩展运算符和for...of进行遍历。
- size 返回元素的个数
- set 增加一个新元素,返回当前Map
- get 返回键名对象的值
- has 检测Map中是否包含某个元素,返回Boolean值
- clear 清空集合,返回undefined
//Map其实就是升级版的对象,key由原来只能是字符串变成现在可以是对象 let m = new Map(); //添加元素 m.set('name','哈哈'); m.set('change', function() { console.log("我们可以改变你!"); }); let key = { school: "heda" } m.set(key,['郑州','开封明伦']) //删除 m.delete('name'); //获取 m.get('change'); //清空 m.clear(); for (const v of m) { console.log(v); }
24、Class类的介绍
ES6提供了更接近传统语法(java ,c 都有类的概念)的写法,引入了class(类)这个概念,作为对象的模板,通过class关键字可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
- class声明类
- constructor定义构造函数初始化
- extends继承父类
- super调用父级构造方法
- static 定义静态方法和属性
- 父类方法可以重写
//ES5通过构造函数实例化对象,语法
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function() {
console.log('我可打电话');
}
//实例化对象
let HuaWei = new Phone('华为',5999);
HuaWei.call();
console.log(HuaWei);
// ES6 写法
class Phone {
// 构造方法 名字固定 无法修改
// 在使用new 关键字 创建对象时自动调用
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 方法必须使用该语法,不能使用ES5的对象完整形式
// call: function (params) {
// }
call() {
console.log('我可打电话');
}
}
let OnePlus = new Phone("1+",1999);
OnePlus.call();
25、Class静态成员
class Phone {
// 静态属性 属于类不属于对象
static name = '手机';
static change() {
console.log('我可以改变世界');
}
}
let nokia = new Phone();
console.log(nokia.name);//undefined
console.log(Phone.name);//手机
26、ES5构造函数继承
unction Phone(brand, price) {
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function () {
console.log('我可打电话');
}
function SmartPhone(brand, price, color, size) {
//此处this指向smartPhone
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
//设置子级构造函数的原型
SmartPhone.prototype = new Phone;
// 声明子类的方法
SmartPhone.prototype.photo = function() {
console.log('我可以拍照');
}
SmartPhone.prototype.play = function() {
console.log('我可以玩游戏');
}
const chuizi = new SmartPhone('锤子',2499,'黑色','5.5inch');
console.log(chuizi);
27、ES6 Class类的继承
//ES6类的继承
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);// Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
photo() {
console.log('我可以拍照');
}
playGame() {
console.log('我可以玩游戏');
}
}
const xiaomi = new SmartPhone('小米',1099,'黑色','4.7inch');
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
28、getter和setter
//get 和 set
class Phone {
get price() {
console.log('价格属性被读取了');
}
set price(value) {
console.log('价格属性被赋值了');
}
}
// 实例化对象
let s = new Phone();
console.log(s.price);
29、数值扩展
Number.EPSILON // 是JavaScript表示的最小精度
console.log(0.1 + 0.2 === 0.3);
function equal(a, b) {
if (Math.abs(a - b) < Number.EPSILON) {
return true;
} else {
return false;
}
}
// 二进制和八进制
let b = 0b1010;
let o = 0o1010;
let d= 100;
let x = 0x10;
Number.isFinite //检测一个数值是否为有限数
console.log(Number.isFinite(100));
Number.isNaN //检测一个数值是否为NaN
console.log(Number.isNaN(100));
Number.parseInt // 字符串转证书
Number.parseInt('435')
Number.isInteger // 判断一个数是否为整数
Math.trunc // 将数字的小数部分抹掉
Math.trunc(3.5)
Math.sign // 判断一个数到底为正数 负数 还是零
30、对象方法扩展
//1. Object.is 判断两个值是否完全相等
console.log(Object.is(120, 120)); //跟===全等号很像,但有区别
console.log(Object.is(NaN, NaN)); // true
console.log(NaN === NaN); //false
//2. Object.assign 对象的合并
const config1 = {
host: 'localhost',
port: 2200,
name: 'admin',
password: '123',
haha: 'fvdvgb'
}
const config2 = {
host: 'https://baidu.com',
port: 5000,
name: 'ceshi',
password: '123456',
}
console.log(Object.assign(config1, config2));//此时config2会覆盖config1重名的属性值
//3. Object.setPrototypeOf 设置原型对象 Object.getPrototypeOf
const school = {
name: "heda"
}
const cities = {
xiaoqu: ['郑州', '开封']
}
Object.setPrototypeOf(school, cities);
console.log(Object.getPrototypeOf(school));
console.log(school);
31、模块化介绍、优势
模块化是指将一个大的程序文件,拆分成许多小问阿金,然后将小文件组合起来。
模块化的好处:
- 防止命名冲突
- 代码复用
- 高维护性
32、浏览器使用ES6模块化
模块功能主要由两个命令构成:export 、 import
export命令用于规定模块的对外接口:
- 分别暴露
- 统一暴露
- 默认暴露
import命令用于输入其他模块提供的功能:
- 通用方式 import * as m1 from “xxx.js”
- 简便形式 import m3 from “xx.js” 只能针对默认暴露
- 解构赋值形式:
import {school as heda, teach} from “xxx.js” import {default as m3} from “xx.js” import {school, teach} from “xxx.js