一、new关键字
    1、new调用构造函数时,发生了什么
    (1)创建一个新对象
    (2)将this指向该新对象
    (3)给this添加属性和方法(包括原型)
    (4)判断返回引用值
    2、模拟new关键字

    1. function myNew(constructor,...args){
    2. let newObj = {}
    3. let res = constructor.apply(newObj,[args])
    4. return (typeof res === 'obj' && typeof res !== null) ? res : newObj
    5. }

    二、call、apply、bind
    1、作用:可以借用某个方法,不用重复定义。
    2、应用场景:
    (1)Object.prototype.toString,用于判断数据类型
    (2)借用构造函数 constructor stealing,实现给父类构造函数传参并解决原型链继承的’值共享’问题
    3、实现call和apply
    核心思想:利用this指向规则(方法作为对象属性调用时,this指向该对象)

    1. function myCall(thisArg,...args){
    2. if(typeof thisArg !== 'function') throw new Error('this must be a function')
    3. let originFunc = this,
    4. functionName = synbol();
    5. thisArg[functionName] = this
    6. return thisArg[functionName](...args)
    7. delete thisArg[functionName]
    8. }
    9. function myApply(thisArg,argsArr){
    10. if(typeof thisArg !== 'function') throw new Error('this must be a function')
    11. let originFunc = this,
    12. functionName = synbol();
    13. thisArg[functionName] = this
    14. return thisArg[functionName](...args)
    15. delete thisArg[functionName]
    16. }

    4、实现bind
    核心思想: 返回一个新函数,执行该函数时,改变this指向。考虑函数prototype属性和使用new关键字调用的情况

    1. function myBind(thisArg, ...formerArgs){
    2. if(typeof thisArg !== 'function') throw new Error ('this must be a funciont')
    3. let originFunction = this
    4. let boundFunction = function (...currentArgs){
    5. let usingNew = this instanceof originFunction;
    6. // 考虑是否用new关键字,是的话,直接返回实例
    7. originFunction.apply(usingNew ? this : thisArg,...formerArgs,...currentArgs)
    8. }
    9. if(originFunction.prototype){
    10. boundFunction.prototype = Object.create(originFunction.prototype)
    11. }
    12. return boundFunction
    13. }