JavaScript前端JavaScriptJavaScript中函数call-apply-bind底层模拟实现寻觅~流光2026-04-192026-04-20apply代码模拟实现123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354/** * cm_apply * 通过js手动实现apply函数 * 1. 给所有函数添加cm_apply方法 ===> 在函数原型上添加临时方法 * 2. 先通过this获取需要执行的这个函数 * 2.1. 判断this是否是函数 * 2.2. 判断是否是undefined与null,直接返回window * 2.3. 判断是否是数字,字符串等原始值,直接使用Object()函数转化为可挂载的对象 * 2.4. 对象即可直接使用 * 3. 使用Symbol()作为key来挂载这个函数 * 4. 处理第二个参数的正确性与规范性 * 4.1. 判断是否传数据 * 4.2. 判断是否为数组,否则报错 * 5. 传入参数并调用挂载的这个函数 * 6. 收集调用结果 * 7. delete 挂载在这个对象上的临时函数 * 8. return这个收集的结果 */Function.prototype.cm_apply = function (context, args) { // 1. 获取需要执行的这个函数 const fn = this; if (typeof fn !== "function") { throw TypeError(fn + " is not a function"); } // 2. 判断context的类型 if (context === undefined || context === null) { context = window; } else { context = Object(context); } // 3. 使用Symbol()作为key来挂载这个函数 const key = Symbol(); context[key] = fn; // 4. 处理第二个参数的正确性与规范性 if (args === undefined) { args = []; } else if (!Array.isArray(args)) { throw new TypeError("CreateListFromArrayLike called on non-object"); } // 5. 传入参数并调用挂载的这个函数 // 6. 收集调用结果 const result = context[key](...args); // 7. delete 挂载在这个对象上的临时函数 delete context[key]; // 8. return这个收集的结果 return result;};call代码模拟实现123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051/** * cm_call * 通过js手动实现call函数 * 1. 给所有函数添加cm_call方法 ===> 在函数原型上添加临时方法 * 2. 先通过this获取需要执行的这个函数 * 2.1. 判断this是否是函数 * 2.2. 判断是否是undefined与null,直接返回window * 2.3. 判断是否是数字,字符串等原始值,直接使用Object()函数转化为可挂载的对象 * 2.4. 对象即可直接使用 * 3. 使用Symbol()作为key来挂载这个函数 * 4. 处理后续参数的正确性与规范性 * 4.1. 判断是否传数据 * 5. 传入参数并调用挂载的这个函数 * 6. 收集调用结果 * 7. delete 挂载在这个对象上的临时函数 * 8. return这个收集的结果 */Function.prototype.cm_call = function (context, ...args) { // 1. 获取需要执行的这个函数 const fn = this; if (typeof fn !== "function") { throw TypeError(fn + " is not a function"); } // 2. 判断context的类型 if (context === undefined || context === null) { context = window; } else { context = Object(context); } // 3. 使用Symbol()作为key来挂载这个函数 const key = Symbol(); context[key] = fn; // 4. 处理后续参数的正确性与规范性 if (args.length === 0) { args = []; } // 5. 传入参数并调用挂载的这个函数 // 6. 收集调用结果 const result = context[key](...args); // 7. delete 挂载在这个对象上的临时函数 delete context[key]; // 8. return这个收集的结果 return result;};bind代码模拟实现12345678910111213141516171819202122232425262728293031323334353637383940414243/** * cm_bind * 通过js手动实现bind函数 * 1. 给所有函数添加cm_bind方法 ===> 在函数原型上添加方法 * 2. 先通过this获取需要执行的这个函数 * 2.1. 判断this是否是函数 * 2.2. 判断是否是undefined与null,直接返回window * 2.3. 判断是否是数字,字符串等原始值,直接使用Object()函数转化为可挂载的对象 * 2.4. 对象即可直接使用 * 3. 处理后续参数的正确性与规范性 * 4.1. 判断是否传数据 * 4.2. 处理分两次传入参数的情况 * 4. return这个返回的函数 */Function.prototype.cm_bind = function (context, ...args) { // 1. 获取需要执行的这个函数 const fn = this; if (typeof fn !== "function") { throw TypeError(fn + " is not a function"); } // 2. 判断context的类型 if (context === undefined || context === null) { context = window; } else { context = Object(context); } // 3. 处理后续参数的正确性与规范性 if (args.length === 0) { args = []; } // 4. return这个返回的函数 return function (...newArgs) { const key = Symbol(); context[key] = fn; const result = context[key](...args, ...newArgs); delete context[key]; return result; };};