ES6规范详解

ES&next

  • 0-20 发展史,babel
  • 20-50 箭头函数、this、arguments
  • 50-60 模板字符串
  • 60-85 Object & Array
  • 85-105 Proxy, reflect, Map, Set

发展历史

  • 浏览器脚本: Javascript;
  • 服务器脚本: PHP / ASP / JSP;

我们需要了解的内容/重点:

  • ECMAScript 是一个标准,JavaScript 是标准的实现;

  • ECMAScript 是 JavaScript 的规格;

  • ECMAScript 的方言,还有 JScript,ActionScript;

  • 浏览器端对于语言特性的实现,有一些滞后;

  • 浏览器在用户侧的升级,也有一些滞后;

ECMAScript / JavaScript -> ES6
浏览器端,商业性的产品,

babel

  • 浏览器的版本,和语言本身有差异,所以我要对语言,进行编译降级。
babel 6
  • ES 的标准:
    • stage 0: strawman 只是一个想法;
    • stage 1: proposal 值得继续的提议;
    • stage 2: draft 草案
    • stage 3: candidate 候选
    • stage 4: finished es2023 spec

babel-preset-stage-2, babel-preset-2016

  • es 的标准每年都会变,babel 6 的问题。
babel 7

preset-env:
targets : []

  • 根据用户的一些浏览器的特性,在运行时动态的引入这些 polyfill (垫片);bundle size 最小。
  • polyfill 是一个概念:垫片。在一个只支持 es5 的浏览器中,去运行 es6 ;

函数解析

new 一个箭头函数会如何?

  • 会报错,提示: function is not a constructor;
  • babel 编译时,会把 this 转成 (void 0);

哪些不能用 箭头函数?

  • arguments
  • yield
  • 构造函数的原型方法上
const Person = function (age, name) {
    this.age = age;
    this.name = name;

    const obj = { '0': 18, '1': 'luyi', '2': 'teacher', '3': 'esnext' };
    console.log(arguments.callee)
    obj.length = 4;
    console.log(Array.prototype.slice.call(obj, 2));
}

// const p = new Person(18, "luyi")

// arguments / callee / caller

const fibonacci = function (num) {
    if (num <= 2) return 1;
    return arguments.callee.caller(num - 1) + arguments.callee.caller(num - 2)
}

console.log(fibonacci(4))

模板字符串

const consoleList = function (student, teacher) {
    console.log(`hello ${student}, I am ${teacher}, nice 2 meet U`)
    // console.log("hello " + student + ", I am " + teacher + ", nice 2 meet U")
}

const consoleString = function (stringTemplate, ...restVal) {
    console.log(stringTemplate.reduce((total, item, index) => total + item + (restVal[index] || ''), ''))
}

const stu = "my students";
const tea = "luyi";

// consoleString(['hello', ', I am ', ', nice 2 meet U'], stu, tea);
// 复杂的模板字符串语法
consoleString`hello ${stu}, I am ${tea}, nice 2 meet U`
const consoleList = function (student, teacher) {
    console.log(`hello ${student}, 
    I am ${teacher}, 
    nice 2 meet U`)
    // console.log("hello " + student + ", I am " + teacher + ", nice 2 meet U")
}

consoleList('my students', 'luyi')

数组和对象

数组和对象的细节

// 数组的细节
// 需要使用 Array.from 或者 .fill(0)
const funcGenerator = (num) => Array.from(new Array(num)).map(item => params => console.log(params));
const funcGenerator = (num) => new Array(num).fill(0).map(item => params => console.log(params));

// funcGenerator(10).map((func, index) => func(index));

// 对象的细节
console.log(NaN === NaN); //false
console.log(Object.is(NaN, NaN)); //true

// ES next 采用了 SameValueZero() 的比较。是一个引擎内置的比较方式。

console.log([NaN].indexOf(NaN))  //-1
console.log([NaN].includes(NaN)) // true SameValueZero

// JS runtime : browser / node

Object.assign

// Object.assign
// 深拷贝还是浅拷贝?

let dist = { foo: "foo" };
let bar = { bar: { bar: "bar" } };
let baz = { baz: "baz" };

const res = Object.assign(dist, bar, baz);

bar.bar.bar = "newBar";
baz.baz = "newBaz"

// 第一层是深拷贝,第二层是浅拷贝;
console.log(res); // { foo: 'foo', bar: { bar: 'newBar' }, baz: 'baz' };
// res -- dist;
console.log(res === dist);
get / set
class Person {
    constructor() {

    }
    _age = "";
    get age() {
        console.log(`actually I am ${this._age} years old~`)
        return "17"
    }

    set age(val) {
        console.log(" It is useless to set my age, I am 17!");
        this._age = val;
    }
}

// const luyi = new Person();
// luyi.age = "35";
// console.log("luyi is", luyi.age);

// java -- mumber private 

//  Proxy 天生的代理模式
// Vue2 Vue3

Proxy

const luyi = {
    age: 35
}

const luyiProxy = new Proxy(luyi, {
    get: function (target, propKey, receiver) {
        console.log("GET:", target, propKey)
        return Reflect.get(target, propKey, receiver);
    },
    set: function (target, propKey, value, receiver) {
        console.log("SET:", target, propKey, value)
        return Reflect.set(target, propKey, value, receiver);
    }
})

console.log(luyiProxy.age = 35)

如何实现断言函数
// 如何去实现一个断言函数?
const assert = new Proxy({}, {
    set(target, warning, value) {
        if (!value) {
            console.error(warning)
        }
    }
})

const teacher = "luyi";
// 如果断言的内容是假的,我就打印
assert['The teacher is Luyi!!!'] = (teacher === "yunyin");
receiver
const luyi = {
    age: 35
}
const luyiProxy = new Proxy(luyi, {
    get: function (target, propKey, receiver) {
        return receiver;
    },
    set: function (target, propKey, value, receiver) {
        console.log("SET:", target, propKey, value)
        return Reflect.set(target, propKey, value, receiver);
    }
})
// receiver 指向原始的读操作所在的那个对象, 一般情况下,就是 Proxy 的实例。
console.log(luyiProxy.age === luyiProxy) // true
Reflect
  1. 将 Object 上一些明显属于语言内部的方法,放到 Reflect 对象上,现在 Object 和 Reflect 一同部署;
  2. 修改某些 Object 方法的返回结果,让其更合理;
const teacher = {
    age: 18, name: "luyi"
}

Reflect.defineProperty(teacher, 'lessions', {
    writable: false,
    enumerable: false,
    configurable: false,
    value: 'vue'
})

const res = Reflect.defineProperty(teacher, 'lessions', {
    writable: true,
    enumerable: true,
    configurable: true,
    value: ['es6', 'esnext']
})

console.log(res);

// Object.defineProperty直接报错: Cannot redefine property: lessions
// Reflect.defineProperty 给 true or false

Map、Set、WeakMap、WeakSet

  • Weak 表示作为唯一的部分,必须是一个对象;
  • Weak 是一个弱引用,不用考虑 GC;
const foos = new WeakSet();

class Foo {
    constructor() {
        foos.add(this);
    }
    method() {
        if (!foos.has(this)) {
            throw new TypeError(" Foo.prototype.method 只能在实例上调用");
        } else {
            console.log("using methods")
        }
    }
}

let f = new Foo();
let b = {};
Foo.prototype.method.call(b)

迭代器,Iterator

  • 迭代器是一个接口,为各种不同的数据提供统一的访问机制。任何数据结构只要部署了 Iterator 接口,就可以完成遍历操作:
    • 本质:指针。
    • 该 接口主要供 for...of 消费。
// let m = new Map();
// m.set('a', 'foo');
// m.set('b', 'bar');
// m.set('c', 'baz');

// let k = m.keys();

// console.log(k.next());
// console.log(k.next());
// console.log(k.next());

let arr = [1, 2, 3, 4, 5];
let k = arr[Symbol.iterator]();

console.log(k.next());
console.log(k.next());
console.log(k.next());
console.log(k.next());
console.log(k.next());
console.log(k.next());

// generator
  • 原生具备 Iterator 的数据结构有:
    Array Map Set String TypedArray arguments NodeList

Object.entries


const obj = { a: 11, b: 22, c: 33 }

console.log(Object.entries(obj)); // [ [ 'a', 11 ], [ 'b', 22 ], [ 'c', 33 ] ]
console.log(Object.keys(obj)); // [ 'a', 'b', 'c' ]
console.log(Object.values(obj)); // [ 11, 22, 33 ]

// 非 generator 的方法
function entries(obj) {
    let arr = [];
    for (let key of Object.keys(obj)) {
        arr.push([key, obj[key]])
    }
    return arr;
}

// generator 的方法
function* entires(obj) {
    for (let key of Object.keys(obj)) {
        yield [key, obj[key]];
    }
}

const k = entires(obj);

console.log(k.next())
console.log(k.next())
console.log(k.next())
console.log(k.next())

for (let item of k) {
    console.log(item)
}

promise.allSettled

function allSettled(array) {
    return new Promise((resolve, reject) => {
        if (!(array instanceof Array)) return reject(new Error(" not Array!"))
        const res = [];
        let count = 0;
        array.forEach((func, index) => {
            Promise.resolve(func).then(value => {
                res[index] = {
                    status: 'fulfilled', value
                }
            }, (reason) => {
                res[index] = {
                    status: 'rejected', reason
                }
            })
                .finally(() => {
                    ++count === array.length && resolve(res);
                })
        })
    })
}

参考网站

https://caniuse.com/ []
https://github.com/tc39/ecma262 []
https://es6.ruanyifeng.com/ [es6 & esnext]
https://juejin.cn/post/6956224866312060942 [babel]

推荐书籍

《你所不知道的 JS》

答疑

老师能归纳数组的扩展里的api 在使用上的一下特点吗
- map =>
- reduce
- filter

手写实现new问得多吗
new 关键字干了什么

ES6的面试重点和难点就是今天讲的这些吗?
- Promise

红杉资本怎么样啊

请教老师一下面试问题,建议是准备差不多了开始面 还是 直接面试,边面试边复盘
- 边面试边复盘

老师仔细说一下 definPropropt 和 Proxy 深层次的区别吗 碰到写框架的 老问这个
- Vue2: 数组、新增、内存消耗大、Proxy lazy 来代理。

老师老师,校招的话大厂比较看重什么,算法吗?
- 算法,聪明

老师刚才断言那个 后面 = yunyin那个可以再说一下嘛

promise class 这些API ,是c++ 实现,还是用现有 旧语法模拟实现提供出来的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值