Skip to content

关键字

new

js
function newFn(constructor, ...args) {
    // 创建空的实例对象
    const instance = {};
    // 如果原型链为对象,则实例对象 __proto__ 指向原型链
    if (isObject(constructor.prototype)) {
        instance.__proto__ = constructor.prototype;
    }
    // 构造器内部的 this 指向实例对象
    const result = constructor.apply(instance, args);
    // 如果返回值为非原始值,则覆盖实例对象
    return isObject(result) ? result : instance;
}
newFn(Foo); // new Foo();

instanceof

js
function instanceofFn(target, constructor) {
    // target 应为对象,constructor 应为函数
    if (!(isObject(target) && typeof constructor === 'function')) {
        return false;
    }
    // constructor.prototype 应为对象
    if (!isObject(constructor.prototype)) {
        throw new TypeError("Function has non-object prototype 'null' in instanceof check");
    }
    // 检查 constructor.prototype 是否在 target 的原型链中
    while (target) {
        if (target.__proto__ === constructor.prototype) {
            return true;
        }
        target = target.__proto__;
    }
    return false;
}
instanceofFn(foo, Array); // foo instanceof Array
Function.prototype[Symbol.hasInstance].call(Array, foo); // foo instanceof Array

async & await

js
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
        var info = gen[key](arg);
        var value = info.value;
    } catch (error) {
        reject(error);
        return;
    }
    if (info.done) {
        resolve(value);
    } else {
        Promise.resolve(value).then(_next, _throw);
    }
}
function _asyncToGenerator(fn) {
    return function () {
        var self = this,
            args = arguments;
        return new Promise(function (resolve, reject) {
            var gen = fn.apply(self, args);
            function _next(value) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value);
            }
            function _throw(err) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err);
            }
            _next(undefined);
        });
    };
}

内置对象

Array

js
class Array {
    reduce(callback, initValue) {
        let acc;
        if (initValue === void 0) {
            if (this.length === 0) {
                throw new TypeError('Reduce of empty array with no initial value');
            }
            acc = this[0];
            for (let i = 1; i < this.length; i++) {
                acc = callback(acc, this[i], i, this);
            }
        } else {
            acc = initValue;
            for (let i = 0; i < this.length; i++) {
                acc = callback(acc, this[i], i, this);
            }
        }
        return acc;
    }
    flat(depth = 1) {
        if (typeof depth !== 'number' || depth === 0) {
            return this;
        }
        let arr = [];
        for (let e of this) {
            arr = arr.concat(Array.isArray(e) ? e.flat(depth - 1) : [e]);
        }
        return arr;
    }
}

Promise

js
const STATUS = {
    PENDING: 'pending',
    FULFILLED: 'fulfilled',
    REJECTED: 'rejected',
};
class Promise {
    _status = 'pending';
    _value = void 0;
    _resolveQueue = [];
    _rejectQueue = [];

    constructor(executor) {
        const handle = (newStatus, queue) => (value) => {
            queueMicrotask(() => {
                if (this._status !== STATUS.PENDING) return;
                this._value = value;
                this._status = newStatus;
                while (queue.length) {
                    queue.shift()(value);
                }
            });
        };
        const resolve = handle(STATUS.FULFILLED, this._resolveQueue);
        const reject = handle(STATUS.REJECTED, this._rejectQueue);
        try {
            executor(resolve, reject);
        } catch (error) {
            reject(error);
        }
    }
    then(onFulfilled, onRejected) {
        onFulfilled =
            typeof onFulfilled === 'function'
                ? onFulfilled
                : (v) => {
                      return v;
                  };
        onRejected =
            typeof onRejected === 'function'
                ? onRejected
                : (e) => {
                      throw e;
                  };
        return new Promise((resolve, reject) => {
            const handle = (callback) => (value) => {
                try {
                    const result = callback(value);
                    result instanceof Promise ? result.then(resolve, reject) : resolve(result);
                } catch (error) {
                    reject(error);
                }
            };
            const resolveFn = handle(onFulfilled);
            const rejectFn = handle(onRejected);
            switch (this._status) {
                case STATUS.PENDING:
                    this._resolveQueue.push(resolveFn);
                    this._rejectQueue.push(rejectFn);
                    break;
                case STATUS.FULFILLED:
                    resolveFn(this._value);
                    break;
                case STATUS.REJECTED:
                    rejectFn(this._value);
                    break;
                default:
                    throw 'Promise 状态错误';
            }
        });
    }

    static resolve(value) {
        return value instanceof Promise ? value : new Promise((resolve) => resolve(value));
    }
    static reject(error) {
        return new Promise((resolve, reject) => reject(error));
    }
    static all(iterable) {
        let count = 0;
        const result = [];
        const array = [...iterable];
        return new Promise((resolve, reject) => {
            if (array.length === 0) {
                return resolve(result);
            }
            array.forEach((p, i) => {
                Promise.resolve(p).then((value) => {
                    result[i] = value;
                    if (++count === array.length) {
                        resolve(result);
                    }
                }, reject);
            });
        });
    }
    static race(iterable) {
        const array = [...iterable];
        return new Promise((resolve, reject) => {
            array.forEach((p) => {
                Promise.resolve(p).then(resolve, reject);
            });
        });
    }
}

A+ 规范

只要有属性 then 且值为函数的任何对象,都是 Promise

Function

js
class Function {
    call(context, ...args) {
        const key = Symbol();
        context[key] = this;
        const result = context[key](...args);
        delete context[key];
        return result;
    }
    bind(context, ...args) {
        const self = this;
        return function (...restArgs) {
            return self.apply(context, args.concat(restArgs));
        };
    }
}

Generator

js
/**生成器函数 */
function* fn() {
    yield 1;
    yield 2;
    yield 3;
    return 23;
}
/**生成器对象,继承于迭代器 */
const foo = fn();
foo.next(); // {value: 1, done: false}
  • 第一次执行 next 时,fn 只会执行到 yield 1; 而不会向下执行
  • 每次执行 next 时,fn 都将继续执行到下一个 yield
  • fn 执行完毕时,next 返回 {value: 23, done: true}
  • 此时再次调用 next 只会返回 {value: undefined, done: true}
js
function* fn() {
    console.log(yield 1);
    yield 2;
    yield 3;
}
const foo = fn();
foo.next(); // {value: 1, done: false}
foo.next(23);
// 23
// {value: 2, done: false}
  • 如果给 next 传入参数,这个参数将作为上一次 yield 的返回值