学习视频:尚硅谷Web前端ES6教程,涵盖ES6-ES11_哔哩哔哩_bilibili
ES:全称为EcmaScript,是脚本语言的规范
ECMAScript: 由Ecma国际通过ECMA-262标准化的脚本程序设计语言。
es6兼容性:ECMAScript 6 compatibility table
1.不能重复声明;(var可以重复声明)
2.块级作用域;
3.不存在变量提升;(变量提升解释:代码执行之前收集变量名称,最初为undefined)
console.log(abc); var abc = 'aaa'; ==》 输出undefined
console.log(abc); let abc = 'aaa'; ==》 报错
4.不影响作用域链;
举例:
1. 一定要赋初始值
2.一般常量使用大写
3.常量的值不能修改
const SCHOOL = '测试';
SCHOOL = 'ABC';
//报错:Uncaught SyntaxError: Missing initializer in const declaration
4.块儿级作用域
{
const SCHOOL1 = '测试';
}
console.log(SCHOOL1);
//报错:Uncaught ReferenceError: SCHOOL1 is not defined at 2-const.html:23
5.对于数组和对象的元素修改,不算做对常量的修改,不会报错
const TEAM = ['ABC','MING','ADF'];
TEAM.push('AD'); //地址不变,所以不报错
TEAM = 100; //会报错
允许按照一定模式从数组和对象中提取值,对变量进行赋值,被称为解构赋值。
ES6允许在大括号里,直接写入变量和函数,作为对象的属性和方法。
输出:
call方法扩展说明:call()
方法是预定义的 JavaScript 方法,它可以用来调用所有者对象作为参数的方法。通过 call()
,您能够使用属于另一个对象的方法。
var person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person1 = {
firstName:"Bill",
lastName: "Gates",
}
var person2 = {
firstName:"Steve",
lastName: "Jobs",
}
person.fullName.call(person1); // 将返回 "Bill Gates"
call() 方法可接受参数:
var person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName:"Bill",
lastName: "Gates"
}
person.fullName.call(person1, "Seattle", "USA"); //out:Bill Gates,Seatle,USA
arguments扩展说明:arguments 是一个对应于传递给函数的参数的类数组对象。arguments 实际上它是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有实参。
arguments展示形式是一个伪数组:具有 length 属性,按索引方式储存数据,不具有数组的 push , pop 等方法。
函数参数(argument)指的是传递到函数或由函数接收到的真实值。
如果调用参数时省略了参数(少于被声明的数量),则丢失的值被设置为:undefined。
function sumAll() {
var i;
var sum = 0;
for(i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
console.log(sumAll(1,2,4)); // out:7
1. 点击div 2s后变色
2. 从数组中返回偶数元素
// 2.需求-2 从数组中返回偶数的元素
const arr = [1,6,9,10,100,25];
//a. 老方法
const result = arr.filter(function(item){
if(item % 2 === 0) {
return true;
}else {
return false;
}
});
console.log(result); //out:(3) [6, 10, 100]
//b. 箭头函数
const result1 = arr.filter(item => item % 2 === 0);
console.log(result1); //out:(3) [6, 10, 100]
总结:箭头函数适合于this无关的回调,如定时器,数组的方法回调
不适合与this有关的回调,如事件回调,对象的方法
let a={
name:'abc',
getName : function(){
return this.name; //this 指向本对象
}
};
var name = 'cccc'; //或window.name可以输出 //当let name='xx'时无法输出,为什么?
let b ={
name:'abc',
getName : ()=> {
console.log(this); //window
return this.name;
} //指向外层this
};
console.log(a.getName()); // out: abc
console.log(b.getName()); // out: cccc
es6允许给函数参数赋初始值
let
Symbol是新引入的数据类型,表示独一无二的值,类似于字符串的数据类型。
特点:1.Symbol值是唯一的,解决命名冲突的问题。2.Symbol值不能与其他数据进行运。 3.Symbol定义的对象属性不能使用for...in循环遍历,可以用Reflect.ownKeys来获取对象的所有键名
//创建Symbol
let s = Symbol();
console.log(s,typeof s); //out: Symbol() 'symbol'
let s2 = Symbol('abc');//传入描述字符串
let s3 = Symbol('abc');
console.log(s2 === s3); // out : false
let s4 = Symbol.for('abc');
console.log(s4,typeof s4); // out: Symbol(abc) 'symbol'
let s5 = Symbol.for('abc');
console.log(s4 === s5); // out: true
//不能与其他数据进行运算
// let result = s + 100; //error: Uncaught TypeError: Cannot convert a Symbol value to a number
// let result = s + s; //error: Uncaught TypeError: Cannot convert a Symbol value to a number
七种数据类型口诀: USONB you are so niubility
//u undefined
//s string symbol
//o object
//n null number
//b boolean
//2 - 使用场景: 向对象中添加方法 up down
let game = {
name:'abc',
up:function(){},
down:function(){}
}
// game.up = function(){}
//声明一个对象
let methods = {
up:Symbol(),
down:Symbol()
};
game[methods.up] = function(){
console.log('我可以改变形状');
}
game[methods.down] = function(){
console.log('我可以快速下降');
}
console.log(game);//out : {name: 'abc', up: ƒ, down: ƒ, Symbol(): ƒ, Symbol(): ƒ}
let youxi = {
name:'狼人杀',
[Symbol('say')]:function(){
console.log('abc');
},
[Symbol('zibao')]:function(){
console.log('efg');
},
}
console.log(youxi);//out:{name: '狼人杀', Symbol(say): ƒ, Symbol(zibao): ƒ}
输出:
除了定义自己使用的Symbol值以外,es6还提供了11个内置的Symbol值,指向语言内部使用的方法
Symbol其他扩展介绍可以参考:
2.3 ES6 Symbol | 菜鸟教程
Symbol - JavaScript | MDN
//当其他对象使用instanseof运算符,判断是否为该对象的实例时,会调用这个方法
class Person{
static [Symbol.hasInstance](param){
console.log(param); // out: {}
console.log('检测类型');
}
}
let o = {};
console.log(o instanceof Person);//out:false
//对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,
//是否可以展开。
const arr = [1,2,3];
const arr2 = [4,5,6];
console.log(arr.concat(arr2));//out: (6) [1, 2, 3, 4, 5, 6]
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));//out:(4) [1, 2, 3, Array(3)]
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,九可以完成遍历操作。
1)es6创造了一种新的遍历命令for..of循环,iterator接口主要供for..of消费
2)原生具备iterator接口 数据(可用for of遍历)
Array, Arguments, Set, Map, String, TypedArray, NodeList
3) 工作原理
a)创建一个指针对象,指向当前数据结构的起始位置
b)第一次调用对象的 next方法,指针自动指向数据结构的第一个成员
c)接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
d)每调用next方法返回一个包含value和done属性对象
//声明一个数组
const arr = ['a','b','c','d'];
for (let v in arr) {
console.log(v+"-"+arr[v]); // out: 0-a 1-b 2-c 3-d
}
//使用for...of遍历数组
for (let v of arr) {
console.log(v); // out: a b c d
}
console.log(arr);
let iterator = arr[Symbol.iterator]();
console.log(iterator);//out:Array Iterator {}
//调用对象的next方法
console.log(iterator.next());//out:{value: 'a', done: false}
console.log(iterator.next());//out:{value: 'b', done: false}
console.log(iterator.next());//out:{value: 'c', done: false}
console.log(iterator.next());//out:{value: 'c', done: false}
console.log(iterator.next());//out:{value: undefined, done: true}
注意:需要自定义遍历数据的时候,需要想到迭代器。
//2 -应用
//注意:需要自定义遍历数据的时候,需要想到迭代器。
const banji = {
name:"终极一班",
stus:[
'marry',
'summer',
'rukawa',
'sakuragi',
'lucy'
],
[Symbol.iterator](){
let index = 0;
let _this = this;
return {
next:function(){
if(index < _this.stus.length) {
const result = {value:_this.stus[index],done:false};
//下标自增
index++;
return result;
}else {
return {value:undefined, done:true};
}
}
};
}
}
//遍历对象,每一次返回的结果是数组里的成员
for (let v of banji) {
console.log(v);//marry summer rukawa sakuragi lucy
}
生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数不同
//异步编程 纯回调函数:node fs ajax mongodb
//加一个星号
function * gen(){
console.log('hello');
}
let iterator = gen();
console.log(iterator);
/**
* out:
* gen
[[GeneratorLocation]]: 12-生成器.html:13
[[Prototype]]: Generator
[[Prototype]]: Generator
constructor: GeneratorFunction {prototype: Generator, Symbol(Symbol.toStringTag): 'GeneratorFunction', constructor: ƒ}
next: ƒ next()
return: ƒ return()
throw: ƒ throw()
Symbol(Symbol.toStringTag): "Generator"
[[Prototype]]: Object
[[GeneratorState]]: "suspended"
[[GeneratorFunction]]: ƒ * gen()
[[GeneratorReceiver]]: Window
[[Scopes]]: Scopes[3]
*
*/
iterator.next(); //out: hello
//yidld函数代码的分隔符
function * gen1(){
console.log(111);
yield '一个';
console.log(222);
yield '二个';
console.log(333);
yield '好的吧';
console.log(444);
}
let it = gen1();
console.log(it.next());//out:111 {value: '一个', done: false}
console.log(it.next());//out:222 {value: '二个', done: false}
console.log(it.next());//out:333 {value: '好的吧', done: false}
console.log(it.next());//out:444 {value: undefined, done: true}
//遍历
for(let v of gen1()){
console.log(v);
}
/**
* out:
111
一个
222
二个
333
好的吧
444
*
*/
//2-生成器的参数传递
function * abc(arg){
console.log(arg);
let one = yield 111;
console.log(one);
let two = yield 222;
console.log(two);
let three = yield 333;
console.log(three);
}
//执行获取迭代器对象
let iterator1 = abc('aaa');
console.log(iterator1.next()); // aaa {value: 111, done: false}
//next 方法可以传入实参
console.log(iterator1.next('bbb'));//bbb {value: 222, done: false}
console.log(iterator1.next('ccc'));//ccc {value: 333, done: false}
console.log(iterator1.next('ddd'));//ddd {value: undefined, done: true}
//3-实例1
//异步编程:文件操作 网络操作(ajax,request) 数据库操作
//1s 后控制台输出 111 2s后输出222 3s后输出333
//老代码:回调地狱
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
}, 1000);
}, 1000);
}, 1000);
console.log("---------------------------");
//改进
function one(){
setTimeout(()=>{
console.log(111);
it1.next();
},1000)
}
function two(){
setTimeout(()=>{
console.log(222);
it1.next();
},1000)
}
function three(){
setTimeout(()=>{
console.log(333);
it1.next();
},1000)
}
function * create1(){
yield one();
yield two();
yield three();
}
//调用生成器函数
let it1 = create1();
it1.next();
//3-实例2
//模拟获取 用户数据 订单数据 商品数据
function getUsers(){
setTimeout(() => {
let data1 = '用户数据';
//调用next方法,并且将数据传入
it2.next(data1);
}, 1000);
}
function getOrders(){
setTimeout(() => {
let data = '订单数据';
it2.next(data);
}, 1000);
}
function getGoods(){
setTimeout(() => {
let data = '商品数据';
it2.next(data);
}, 1000);
}
function * create2(){
let users = yield getUsers();
console.log(users);
let orders = yield getOrders();
console.log(orders);
let goods = yield getGoods();
console.log(goods);
}
//调用生成器函数
let it2 = create2();
it2.next();
Promise是es6引入的异步编程的新解决方案,语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
构造函数:Promise(excutor){}
Promise.prototype.then方法
Promise.prototype.catch方法
//实例化promise对象
//初始化 成功 失败
const p = new Promise(function(resolve,reject){
setTimeout(function(){
// let data = '数据库中的用户数据';
// //resolve
// resolve(data); //成功时调用
let err = '数据读取失败';
reject(err); //失败时调用
},
1000);
});
//调用promise 对象的 then方法
p.then(function(value){ //成功
console.log(value); // out: 数据库中的用户数据
},function(reason){//失败
console.log(reason); // out: 数据读取失败
})
(二) 封装读取文件
// //1.引入fs模块
const fs = require('fs');
// //2. 调用方法读取文件
// fs.readFile('../resources/1.txt',(err,data)=>{
// //如果失败,抛出错误
// if(err) throw err;
// //如果正确,则输出
// console.log(data.toString());
// });
//3.使用promise封装
const p = new Promise(function(resolve, reject){
fs.readFile('../resources/1.txt',(err,data)=>{
//如果失败
if(err) reject(err);//改变状态为失败
//如果正确,改变状态为成功,并传值
resolve(data);
});
});
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log('读取失败');
});
控制台输入:node .\13-promise读取文件.js
打印出文件内容