加载中...

ES6新特性(上)


ES6新特性(上)

  1. let和const命令
  2. es6的模板字符串
  3. 增强的函数
  4. 解构赋值
  5. 扩展的字符串、对象、数组功能
  6. Symbol
  7. Map和Set
  8. 迭代器和生成器
  9. Promise对象
  10. Proxy对象
  11. async的用法
  12. 类 class
  13. 模块化实现

参考链接:

9~13章请看→ES6新特性(下)篇:https://wuyea.top/posts/2559352444.html

1. let和const命令

let命令

特性:

  1. 不存在变量提升。
  2. 只在let命令所在的代码块内有效。
  3. 不能重复声明。
  4. 不会污染全局变量。

const命令

特性:

  1. const的作用域与let命令相同:只在声明所在的块级作用域内有效。
  2. 一旦声明变量,就必须立即初始化,且不可更改。

2. 模板字符串

模板字符串:使用tab键上面的反引号``, 插入变量时使用 ${变量名}

示例:

<html>
    <head>
        <title>模板字符串</title>
    </head>
    <body>
        <div class="box">
        </div>
        <script>
            const oBox = document.query.Selector('.box');
          	let id=1,name="wuye";
            let htmlStr = `<ul>
            	<li>
            		<p id=${id}>${name}</p>
        		</li>
    		</ul>`;
            oBox.innerHTML = htmlStr;
        </script>
    </body>
</html>

3. 增强的函数

函数参数的默认值

示例:

function add(a, b=20){
    return a + b;
}
console.log(add(30));

默认的表达式也可以是一个函数

function add(a, b=getVal(5)){
    return a + b;
}

function getVal(val){
    return val + 5;
}

console.log(add(10));

剩余运算符

解释:把多个独立的参数合并到一个数组中。

使用:由三个点…和一个紧跟着的具名参数指定 …keys

function pick(obj, ...keys) {
    // ...keys 解决了 arguments 的问题
    let result = Object.create(null);
    for(let i=0;i< keys.length; i++) {
        result[keys[i]]= obj[keys[i]];
    }
	return result;
}

let book = {
	title:'es6的教程',
    author:'wuye',
	year:2024
}
let bookData = pick(book, 'year', 'author');
console.log(bookData);

function checkArgs(...args) {
    console.log(args);
    console.log(arguments);
}
checkArgs('a', 'b', 'c');

扩展运算符

解释:将一个数组分割,并将各个项作为分离的参数传给函数

const arr = [10,20,50,40,90,100];
console.log(Math.max.apply(null, arr)); // es5写法
console.log(Math.max(...arr)); // es6的扩展运算符

箭头函数

使用 => 来定义,取代了 function(){} ,等价于 ()=>{}

示例1:

let add = function(a, b) {  // es5
    return a + b;
}

let add = (a, b) => { // es6
    return a + b;
}
console.log(add(10,20));

示例2:

let add = val => {
    return val + 5;
}
// 上面的等价与下面
let add = val => (val + 5);  // (val + 5) 就是 {return val+5}

let add = val => val;  // 等价于:let add = val=>(val); 也可以省略小括号

console.log(add(10));

let add = (val1, val2) => val1 + val2;
console.log(add(10, 20));

// 如果没有参数
let fn = () => 'hello world' + 123;
console.log(fn());

let getObj = id => ({id:id, name:"wuye"}); // 此时一定需要小括号
let obj = getObj(1);
console.log(obj);

箭头函数中的this指向

注意:箭头函数没有this指向,箭头函数内部this只能通过查找作用域链来确定,一旦使用箭头函数,当前就不存在作用域链

使用箭头函数的注意事项

  1. 使用箭头函数,函数内部没有arguments。

  2. 箭头函数不能使用new关键字来实例化对象。

    function函数 也是一个对象,但是箭头函数不是一个对象,它其实就是一个语法糖。

4. 解构赋值

解构赋值是对赋值运算符的一种扩展,它针对数组和对象来进行操作。

优点:代码书写上简洁易读。

示例一:完全解构

let node = {
    type: 'iden',
    name: 'foo'
}
// es5写法:
// let type = node.type;
// let name = node.name;

// es6写法:
let {type, name} = node;
console.log(type, name)

示例二:不完全解构,可忽略

let obj = {
    a: {
        name: "张三"
    },
    b: [],
    c: "hello world"
}

let {a} = obj; // 不能写成 let {f} = obj, 不支持对名称重命名
console.log(a);
// 剩余运算符
let {a, ...res} = obj;
console.log(res);

示例三:对数组解构

let arr =[1,2,3];
let [a,b]= arr;
console.log(a,b);

// 可嵌套
let [a,[b],c]=[1,[2],3];

// 默认值: a=20, b=30
let {a, b=30} = {a:20};

5. 扩展的对象功能

es6直接写入变量和函数,作为对象的属性和方法

示例一:

const name='wuye', age='18';
const person = {
    name,  // 等价于  name:name
    age,   // 等价于  age:age
    [name + '_bak'] = 'wuye', // 等价于 wuye_bak='wuye', [name+'_bak']就是字符串拼接
    sayName() {  // 等价于  sayName: function()
        console.log(this.name);
    }
}
person.sayName();

示例二:

// is() ===    比较两个值是否严格相等
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true

// assign()    对象的合并
// Object.assign(target, obj1, obj2......)
let newObj = Object.assign({}, {a:1}, {b:2});  // 返回合并之后的新对象
console.log(newObj); // {a:1, b:2}

6. Symbol类型

原始数据类型Symbol,它表示是独一无二的值(内存地址不相同)。

如果用Symbol定义的对象中的变量,取值时一定要用 [变量名]

最大用途:用来定义对象的私有变量。

const name = Symbol('name');
const name2 = Symbol('name');
console.log(name === name2); // false  因为内存地址不相同

let s1 = Symbol('s1');
let obj = {[s1]: 'wuye'}
console.log(obj[s1])  // wuye
console.log(obj.s1)   // undefined

//获取Symbol声明的属性名(作为对象的key)
let s = Object.getOwnPropertySymbols(obj);
console.log(s[0]);
let m = Reflect.ownKeys(obj);
console.log(m[0]);

7. Map和Set

Set

集合:表示无重复值的有序列表

let set = new Set(); // 创建空集合
console.log(set);
//添加元素
set.add(2);
set.add([1,2,3]);
// 删除元素
set.delete(2);
// 校验某个值是否在set中
set.has('4')

// 通过扩展运算符将set转化为数组
let set2 = new Set([1,2,3,3,3,4]);
let arr = [...set2]
console.log(arr);

非重点)因为set无法释放对象,所以有 WeakSet,但是需要注意:

  1. 不能传入非对象类型的参数
  2. 不可迭代
  3. 没有forEach()
  4. 没有size属性
/* let set3 = new Set(), obj={};
set3.add(obj);
obj = null; // 释放当前的资源
console.log(set3); */

let set4 = new WeakSet(), obj = {};
set4.add(obj);
obj = null; // 释放当前的资源
console.log(set4);

Map

Map类型是键值对的有序列表,键和值是任意类型。

let map = new Map();
map.set('name','张三');
map.set('age',20);
console.log(map.get('name'));
console.log(map);
map.has('name'); // true

8. 迭代器和生成器

迭代器 Iterator

Iterator是es6引入的一种新的遍历机制。两个核心:

  1. 迭代器是一个统一的接口,它的作用是使各种数据结构可被便捷的访问,它是通过一个键为Symbol.iterator 的方法来实现。
  2. 迭代器是用于遍历数据结构元素的指针(如数据库中的游标)。
// 使用迭代
// 1.使用Symbol.iterator创建一个迭代器
// const items = ['one','two','three'];
// // console.log(items);
// const it = items[Symbol.iterator]();
// console.log(it);
// 2.调用next方法向下迭代,next方法会返回当前的位置
// const nextEle = it.next();
// 3.当done为true时则遍历结束
// console.log(nextEle);

// 可迭代的数据结构
// Array String MaSet    
// 但是对象是不能迭代
// 跟迭代紧密相关的就是for...of循环
// for(let item of items){
//     console.log(item);
// }
// 将对象转换成数组
const arrayLink = {length: 2, 0: "zero", 1: "one"}
console.log(Array.from(arrayLink));

for(let item of Array.from(arrayLink)){
	console.log(item);   
}

生成器 Generator

es6新引入了Generator函数,可以通过yield关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而也为了异步编程提供了解决方案。
它跟普通函数的区分:

  1. 在function后面,函数名之前有个*
  2. 函数内部有yield(产出)表达式
// *表示函数为Generator函数,
function* func(a) {
    console.log('one');
    yield a;
    console.log('two');
    yield '2';
    console.log('three');
    return 3;
}
//   每次执行函数都会返回一个遍历器对象
let fn = func(1); // 此时函数不会真的执行,只是返回一个遍历器对象
console.log(fn);
//   必须调用遍历器对象的next方法,使得指针移向下一个状态
//   console.log(fn.next());
//   console.log(fn.next());
//   console.log(fn.next());
//   总结: Generator函数是分段执行的,yield语句是暂停执行,而next方法可以恢复执行

function* add() {
    console.log('start');
    // x 可真的不是yield '2'的返回值,它是next()调用 恢复当前yield()执行传入的实参
    var x = yield '2';
    console.log('one:' + x);
    var y = yield '3';
    console.log('two:' + y);
    console.log('total:' + (x + y)); 
    return x+y;
}
const a = add();
console.log(a.next());   // {value:'2', done:false}
console.log(a.next(20)); // {value:'3', done:false}
console.log(a.next(30)); // {value:50, done:true}

使用场景:为不具备Interator接口的对象提供了遍历操作

// 使用场景,为不具备Interator接口的对象提供了遍历操作
function* objectEntries(obj) {
    // 获取对象的所有key 存储到数组中
    const propKeys = Object.keys(obj);
    // console.log(propKeys);
    for (const propKey of propKeys) {
        yield [propKey, obj[propKey]];
    }
}

const obj = {
    name: 'Jane',
    age: 18
}

obj[Symbol.iterator] = objectEntries;
console.log(obj);

for (const [key, value] of objectEntries(obj)) {
    console.log(`${key}: ${value}`);
}

文章作者: 无夜
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 无夜 !
评论
  目录