diff --git "a/\346\211\213\345\206\231\344\270\200\344\270\252apply.js" "b/\346\211\213\345\206\231\344\270\200\344\270\252apply.js" index d2ff99f..fc8f7c8 100644 --- "a/\346\211\213\345\206\231\344\270\200\344\270\252apply.js" +++ "b/\346\211\213\345\206\231\344\270\200\344\270\252apply.js" @@ -1,14 +1,28 @@ -Function.prototype.myApply = function(context, arr) { +function copySymbol(obj) { + const unique_proper = "00" + Math.random(); + if (obj.hasOwnProperty(unique_proper)) { + arguments.callee(obj)//如果obj已经有了这个属性,递归调用,直到没有这个属性 + } else { + return unique_proper; + } +} +const isArray = (obj) => Object.prototype.toString.call(obj).slice(8, -1).toLocaleLowerCase() === 'array' +Function.prototype.myApply = function (context, arr) { if(typeof this !== 'function') { return 'err' } context = context || window - context.fn = this + const fnName = copySymbol(context) + context[fnName] = this let res - if(!arr) { - res = context.fn() + if (arr) { + if (!isArray(arr)) { + throw '第二个参数必须是数组' + } + res = context[fnName](...arr) //如果有返回值 + } else { + res = context[fnName]() } - res = context.fn(...arr) //如果有返回值 - delete context.fn + delete context[fnName] return res } \ No newline at end of file diff --git "a/\346\211\213\345\206\231\345\256\236\347\216\260new.js" "b/\346\211\213\345\206\231\345\256\236\347\216\260new.js" index d05fa1f..55b0d6e 100644 --- "a/\346\211\213\345\206\231\345\256\236\347\216\260new.js" +++ "b/\346\211\213\345\206\231\345\256\236\347\216\260new.js" @@ -4,4 +4,30 @@ function copyNew(){ obj.__proto__ = Constructor.prototype const res = Constructor.apply(obj,[...arguments].slice(1)) return res && (typeof res === 'object') ? res : obj -} \ No newline at end of file +} + + +const isObject = (obj) => typeof obj === 'object' && obj !== null +const isFunction = (fn) => typeof fn === 'function' + +function newOperator(Constructor, ...args) { + if (typeof Constructor !== 'function') { + throw '第一个参数必须是一个函数' + } + // newOperator.target = Constructor + const newObj = Object.create(Constructor.prototype) + const res = Constructor.call(newObj, ...args) + if (isObject(res) || isFunction(res)) { + return res + } + return newObj +} + +/** + * new 做了什么 + * 1. 创建一个新的对象 + * 2. 这个对象的__proto__, 会指向构造函数的prototype + * 3. this指向这个新到对象 + * 4. 执行构造函数中到代码 + * 5. 如果该构造函数返回的是引用类型,那么会返回该引用类型,否则返回这个新的对象 + */ \ No newline at end of file