es6-新特性

let

1、let变量不能重复声明
2、let块级作用域(全局、函数、eval等)

{
    let name = "孙悟空";
 }
 console.log(name);//此处name不能访问

3、不存在变量提升

console.log(song);//会报错
let song = "歌曲";

4、不影响作用域链

let song = "歌曲";
 function toSong() {
     console.log(song);
}
toSong();//可以正常打印

const

用来声明常量
1、一定要赋初始值
2、一般常量使用大写
3、常量的值不能修改
4、块儿级作用域
5、对数组和对象中的元素修改,不算做对常量的修改,不会报错

const ARR = ["uzi"];
ARR.push("meikou");

变量的解构赋值
1、数组的解构

const FOUR = ["小沈阳","刘能","赵四","宋小宝"];
let [xiao,liu,zhao,song] = FOUR;
console.log(xiao,liu,zhao,song);//小沈阳 刘能 赵四 宋小宝

2、对象的解构

const zhao = {
   name:"赵本山",
   age:67,
   skill: function() {
      console.log("演小品");
   }
};
let {name,age,skill} = zhao;
console.log(name,age);//赵本山 67
skill();//演小品

模版字符串

1、使用反引号` `声明

let str = `我是一串模版字符串`;

2、内容中可以直接出现换行符

let str = `<ul>
            <li>one</li>
            <li>two</li>
            </ul>`;

3、变量拼接
使用${ }进行拼接

let name = `山东`;
let content = `${name}高铁里程第一`;
console.log(content);//山东高铁里程第一

对象的简化写法

es6允许在大括号用,直接写入变量和函数,作为对象的属性和方法

let name = `赵四`;
let skill = function() {
    console.log(`会跳高`);
}
const info = {
    name,
    skill,
    study(){
        console.log(`学习很好`);
     }
}

箭头函数

声明
()=> {}等价于function() {} 例如:

let fn = (a, b) => {
     return a + b;
};
console.log(fn(3,4));//7

特性
1、this是静态的,this始终指向函数声明时所在作用域下的this的值;
例如:使用call()改变this会报错
2、不能作为构造实例化对象
3、不能使用arguments变量,会报错
4、箭头函数的缩写

1、省略小括号
当形参有且只有一个的时候可以省略小括号

let add = n=> {
  return n+ n;
}

2、省略花括号
当代码体只有一条语句的时候可以省略花括号,而且return也要省略。

let add = n => n + n;

函数参数默认值
1、形参初始值,具有默认值的参数,一般位置要靠后

function add(a,b,c=10) {
      return a + b + c;
}
let fn = (a, b=10) => {
      return a + b;
};

2、与解构赋值结合

function connect({ a = "123", b, c }) {
      return a + b + c;
}
let result = connect({
       b: "4",
       c: "5"
});
console.log(result);//"12345"

rest参数
用于获取函数的实参,用来代替arguments

function date(...args) {
     console.log(args);
}
date("a","b","c");//['a', 'b', 'c']

如果有多个参数,rest参数必须放在参数的最后。

扩展运算符
能将数组转换为逗号分隔的参数序列

const boys = [`a`, `b`, `c`];
function chunwan() {
    console.log(arguments);
}
chunwan(...boys);//等价于chunwan(`a`, `b`, `c`);

可将伪数组转换为真正的数组

window.onload = () => {
    let divs = document.getElementsByTagName(`div`);
    let realDivs = [...divs];
    console.log(realDivs);
}

Symbol---新数据类型

创建

let s = 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

不能与其他数据进行运算

对象添加Symbol类型属性
方式一:

let game = { };
let methods = {
   up: Symbol(),
   down: Symbol()
};
game[methods.up] = function () {
   console.log(`上`);
};
game[methods.down] = function () {
   console.log(`下`);
};
console.log(game);

方式二:

let game = {
   name: `三国杀`,
   [Symbol(`say`)]: function () {

   }
}
console.log(game);

Symbol内置属性
1、Symbol.hasInstance当其他对象使用instanceof运算符,判断是否为该对象实例时,会调用这个方法。

class Person {
   static [Symbol.hasInstance](){
      console.log("我被用来检测类型的");
      return false;
   }
}
let obj = {};
console.log(obj instanceof Person);

2、Symbol.isConcatSpreadable对象的该属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。

const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));

3、其他属性

属性 含义
Symbol.unscopables 该对象指定了使用with关键字,哪些属性会被with环境排除
Symbol.match 当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。
Symbol.replace 当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值
Symbol.search 当该对象被str.search(myObject)方法调用时,会返回该方法的返回值
Symbol.split 当该对象被str.split(myObject)方法调用时,会返回该方法的返回值
Symbol.iterator 对象进行for...of循环时,会调用该方法,并返回该对象的默认遍历器
Symbol.toPrimitive 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原型类型值
Symbol.toStringTag 在该对象上面调用toString方法时,返回该方法的返回值
Symbol.species 创建衍生对象时,会使用该属性

说白了Symbol就是扩展了对象的功能。

迭代器

迭代器(iterator)是一种接口,为各种不同的数据提供统一的访问机制;任何数据结构只要部署iterator属性,就可以完成遍历操作。
1、es6创建了新的遍历命令for...ofiterator接口,主要提供for...of消费;
2、原生具备iterator接口的数据(可用for...of遍历):

Array
Arguments
Set
Map
String
TypeArray
NodeList

3、工作原理:

1)创建一个指针对象,指向当前数据结构的起始位置;
2)第一次调用对象的next方法,指针自动指向数据结构的第一个成员;
3)接下来不断调用next方法,指针一致往后移动,直到指向最后一个成员;
4)每调用next方法返回一个包含valuedone属性的对象。

const xiyou = [`唐僧`, `孙悟空`, `猪八戒`, `沙和尚`];
let iterator = xiyou[Symbol.iterator]();
console.log(iterator.next());//{value: '唐僧', done: false}
console.log(iterator.next());//{value: '孙悟空', done: false}
console.log(iterator.next());//{value: '猪八戒', done: false}
console.log(iterator.next());//{value: '沙和尚', done: false}
console.log(iterator.next());//{value: undefined, done: true}

自定义遍历数据

const xiyouji = {
   name: `西游记`,
   persons: [`唐僧`, `孙悟空`, `猪八戒`, `沙和尚`],
   //工作原理:1)创建一个指针对象,指向当前数据结构的起始位置;
   [Symbol.iterator]() {
      let index = 0;
      let _this = this;
      return {
         //2)第一次调用对象的```next```方法,指针自动指向数据结构的第一个成员;
         next: function () {
            if (index < _this.persons.length) { 
               const result={value: _this.persons[index],done: false}; 
               //3)接下来不断调用```next```方法,指针一致往后移动,直到指向最后一个成员;
               index++; 
               //4)每调用```next```方法返回一个包含```value```和```done```属性的对象。
               return result; 
            } else {
               return {value: undefined, done: true};
            } 
        }
     }
   } 
};
for (const person of xiyouji) { 
   console.log(person); 
}

生成器
其实就是一个特殊的函数;
异步编程,纯回调函数:nodefsajaxmongodb
声明:声明函数,函数名前加*,通过yield把函数分为多段,每次调用next方法都会执行一段

function* gen() {
   console.log(`第一段`);
   yield `1`;
   console.log(`第二段`);
   yield `2`;
   console.log(`第三段`);
   yield `3`;
   console.log(`第四段`);
}
// let iterator = gen();
// iterator.next();
// iterator.next();
// iterator.next();
// iterator.next();

for (const y of gen()) {
   console.log(y);
}
//输出结果
/*
第一段
1
第二段
2
第三段
3
第四段
*/

生成器函数参数
next()方法是可以传参的,会作为yield的返回结果

function* gen(arg) {
      console.log(arg);
      let one = yield `1`;
      console.log(one);
      let two =yield `2`;
      console.log(two);
      let three = yield `3`;
      console.log(three);
}
let iterator = gen(`AAA`);
console.log(iterator.next());//AAA {value: '1', done: false}
console.log(iterator.next("BBB"));//BBB {value: '2', done: false}
console.log(iterator.next("CCC"));//CCC {value: '3', done: false}
console.log(iterator.next("DDD"));DDD {value: undefined, done: true}

生成器函数实例

function one() {
      setTimeout(() => {
          console.log(111);
          iterator.next();
      }, 1000);
}
function two() {
      setTimeout(() => {
          console.log(222);
          iterator.next();
      }, 1000);
}
function three() {
      setTimeout(() => {
          console.log(333);
          iterator.next();
      }, 1000);
}
function *gen() {
      yield one();
      yield two();
      yield three();
}

let iterator = gen();
 iterator.next();

Promise

es6引入的异步编程的新解决方案,Promise是一个构造函数;
用来封装异步操作并可以获取其成功或失败的结果。

1)Promise构造函数:Promise(excutor){}
2)Promise.prototype.then方法
3)Promise.prototype.catch方法

创建
成功调用resolve方法获取数据,失败调用reject方法返回错误。

const p = new Promise(function (resolve, reject) {
      setTimeout(() => {
          let data = `数据库中的用户数据`;
          //成功
          resolve(data);
          //ject(`失败`);
      }, 1000);
});
p.then(function (value) {
      //成功
      console.log(value);
}, function (reason) {
      //失败
      console.error(reason);
});

Promise封装读取文件
需要Node.js环境

const fs = require(`fs`);

const p = new Promise(function (resolve, reject) {
    fs.readFile(`./es6/为学.md`, (error, data) => {
        if (error) reject(error);

        resolve(data);
    });
});

p.then(function (value) {
    console.log(value.toString());
}, function (reason) {
    console.error(reason);
});

Promise封装Ajax请求

const p = new Promise(function (resolve, reject) {
    //创建对象
    const xhr = new XMLHttpRequest();
    //初始化
    xhr.open("GET", "https://api.apiopen.top/getJoke");
    //发送
    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);
            }
        }
    };
});
p.then(function (value) {
    console.log(value);
}, function (reason) {
    console.error(reason);
});

Promise嵌套处理多个请求

const fs = require(`fs`);

const p = new Promise(function (resolve, reject) {
    fs.readFile(`./es6/为学.md`, (error, data) => {
        if (error) reject(error);

        resolve(data);
    });
});

p.then(function (value) {
    //这里返回一个Promise对象,便于then接收
    return new Promise(function (resolve, reject) {
        fs.readFile(`./es6/爱莲说.md`, (error, data) => {
            if (error) reject(error);
            resolve([value, data]);
        });
    })
}, function (reason) {
    console.error(reason);
}).then(value => {
    console.log(value.join(`\r\n`));
}, reason => {
    console.error(reason);
});

catch方法
相比then方法,catch方式只指定失败的参数

p.catch(function (reason) {
    console.error(reason);
});

集合Set

声明
Set可以对数组进行去重

let s = new Set([`1`,`2`,`3`,`1`,`2`]);
console.log(s);// 1 2 3

方法
add添加
delete删除
has检查
clear清空

s.add(`6`);
s.delete(`1`);
console.log(s.has(`2`));
s.clear();

可以使用for...of遍历

for (const n of s) {
    console.log(n);
}

实践
1、数组去重
使用...Set转回数组

let arr = [`1`, `2`, `3`, `1`, `2`];
let result = [...new Set(arr)];
console.log(result);

2、交集

let arr = [`1`, `2`, `3`, `1`, `2`];
let arr2 = [`1`, `2`, `3`, `5`, `6`];
let result = [...new Set(arr)].filter(item=>(new Set(arr2)).has(item));
console.log(result);

3、并集

let arr = [`1`, `2`, `3`, `1`, `2`];
let arr2 = [`1`, `2`, `3`, `5`, `6`];
let result = [...new Set([...arr,...arr2])];
console.log(result);

注意:...数组是把数组转化为以逗号隔开的字符串

4、差集
相当于交集取反

 let result = [...new Set(arr)].filter(item=>!(new Set(arr2)).has(item));

注意前后差集是不一样的

Map

声明
键值对形式,键值可以是字符串、对象、函数等等

let m = new Map();

属性方法
set添加
size大小
delete删除
get获取
clear清空

m.set(`name`,`名字`);
console.log(m.size);
m.delete(`name`);
console.log(m.get(`name`));
m.clear();

还可以通过for...of遍历

for (const v of m) {
    console.log(v);
}

遍历后v是一个数组,第一个元素是key,第二个元素是value

Class---类

声明

class Phone {
    //必须使用constructor关键字,不能修改
    constructor(brand, price) {
        this.brand = brand;
        this.price = price;
    }
    //必须使用call(){}语法
    call() {
        console.log(`我可以打电话`);
    }
} 
let apple = new Phone(`iPhone 17`,5999);
console.log(apple);

class静态成员
类的属性和方法是属于类的,不是属于实例的

class Phone {
    static name = `手机`;
    static change() {
        console.log(`我可以改变世界`);
    };
}
let nokia = new Phone();
console.log(nokia.name);//undefined 
console.log(Phone.name);//手机
Phone.change();//我可以改变世界

class继承

class SmartPhone extends Phone {
    constructor(brand, price, color, size) {
        super(brand, price);
        this.color = color;
        this.size = size;
    }
}
let xiaomi = new SmartPhone(`小米`,799,`黑色`,`4.7inch`);
console.log(xiaomi);
xiaomi.call();

子类重写父类方法
子类中声明一个和父类相同的方法,即实现重写

class的getter和setter方法

class Car {
    constructor(price) {
        this._price = price;
    }
    get price() {
        console.log(`走getter了`);
        return this._price;
    }
    set price(newValue) {
        console.log(newValue);
        this._price = newValue;
    }
}
let car = new Car();
car.price = `30w`;
console.log(car.price);

数值/对象方法扩展

扩展 含义
Number.EPSILON 属性,表示最小精度,用于判断浮点数是否相等,如果两个数的差小于该值,就判断这两个数相等
Number.isFinite 方法,检测一个数值是否为有限数
Number.isNaN 方法,检测一个数值是否为NaN
Number.parseIntNumber.parseFloat 方法,字符串转整数、浮点数
Number.isInteger 方法,判断一个数是否为整数
Math.trunc 方法,将数字的小数部分抹掉
Math.sign 方法,判断一个数到底是正数(返回1)、负数(返回-1)、还是零(返回0)
进制 0b开头二进制
0o开头八进制
0x开头十六进制
Object.is 方法,判断两个值是否完全相等
Object.assign 方法,对象的合并
1、如果参数相同,后面对象会把前面对象覆盖
2、不同会合并
Object.setPrototypeOfObject.getPrototypeOf 方法,设置原型对象、获取原型对象
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容