模拟实现函数-Function.prototype.xxx
# bind
# 关于 bind
bind()方法创建一个新的函数- 在
bind()被调用时- 这个新函数的
this被指定为bind()的第一个参数 - 其余参数将作为新函数的参数,供调用时使用
- 这个新函数的
# bind-MDN 实现
Function.prototype.myBind = function () { var thatFunc = this; var thatArgs = arguments[0]; var args = [].slice.call(arguments, 1); if (typeof thatFunc !== 'function') { throw new TypeError( 'Function.prototype.bind - ' + 'what is trying to be bound is not callable' ); } return function () { var funcArgs = args.concat([].slice.call(arguments)); return thatFunc.apply(thatArgs, funcArgs); }; };jscopy success
# call
# call-实现
思路,分三步:
// 第一步:借方法 obj.fn = func; // 第二步:执行方法 obj.fn(); // 第三步:还方法 delete obj.fn;jscopy success
Function.prototype.myCall = function (context) { // null => window var context = context || window; // 借方法 // fn 可能已存在,此处严谨的写法是:uniqueName context.fn = this; // 取参数 - es5 var args = []; for (var i = 1, len = arguments.length; i < len; i++) { args.push('arguments[' + i + ']'); } // 执行方法 var result = eval('context.fn(' + args + ')'); // // 取参数 - es6 // for (let i = 1, len = arguments.length; i < len; i++) { // args.push(arguments[i]); // } // // 执行方法 // var result = context.fn(...args); // 还方法 delete context.fn; // 函数可以有返回值 return result; };jscopy success
# apply
与 call 实现很相似,只需要考虑数参数。
Function.prototype.myApply = function (context, arr) { // null => window var context = context || window; // 借方法 // fn 可能已存在,此处严谨的写法是:uniqueName context.fn = this; var result; if (!arr) { result = context.fn(); } else { // result = context.fn(...arr); var args = []; for (var i = 0, len = arr.length; i < len; i++) { args.push('arr[' + i + ']'); } result = eval('context.fn(' + args + ')'); } // 还方法 delete context.fn; // 函数可以有返回值 return result; };jscopy success
# Object.create
Object.prototype.myCreate = function (obj) { function F() {} F.prototype = obj; return new F(); };jscopy success
# new
# new 做的事情
- 创建一个空的简单 JavaScript 对象(即{})
- 链接该对象(即设置该对象的构造函数)到另一个对象
- 将步骤 1 新创建的对象作为 this 的上下文
- 如果该函数没有返回对象,则返回 this
# new 代码实现
// myNew(Person, 'cxk', '18') function myNew() { const obj = new Object(); const Constructor = [].shift.call(arguments); obj.__proto__ = Constructor.prototype; const ret = Constructor.apply(obj, arguments); return typeof ret === 'object' ? ret : obj; } // 2 function myNew() { //1.拿到传入的参数中的第一个参数,即构造函数名Func var Func = [].shift.call(arguments); //2.创建一个空对象obj,并让其继承Func.prototype var obj = Object.create(Func.prototype); //3.执行构造函数,并将this指向创建的空对象obj Func.apply(obj, arguments); //4.返回创建的对象obj return obj; }jscopy success
# instanceOf
// 模拟 instanceof function myInstanceof(L, R) { var O = R.prototype; L = L.__proto__; while (true) { if (L === null) { return false; } // 这里重点:当 O 严格等于 L 时,返回 true if (O === L) { return true; } L = L.__proto__; } }jscopy success