面试题:实现call、apply、bind
生活随笔
收集整理的這篇文章主要介紹了
面试题:实现call、apply、bind
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
面試題:實現call、apply、bind
實現bind
module.exports = function(Tcontext, ...args) {let globalThis = typeof window === "undefined" ? global : window;let context = typeof Tcontext === "undefined" ? globalThis : Tcontext;let withArgs = args.length != 0; //是否傳參if (!!this.prototype && typeof context === "object" && context !== null) {//context是有效對象return withArgs? () => Object.assign(context, new this(...args)) //若帶參,返回的函數不需要處理接收參數: (...args) => Object.assign(context, new this(...args)); //若不帶參,返回的函數需要處理接收參數} else {return withArgs? ()=>this(...args): (...args)=>this(...args)} }; 復制代碼實現call
在實現了bind后,只需要將call轉換給bind處理就可以了
module.exports = function(context, ...args){return this.newBind(context, ...args)() } 復制代碼實現apply
實現了call后,只需要處理下參數,轉換給call處理就可以了
module.exports = function(context, args){return args instanceof Array?this.newCall(context, ...args):this.newCall(context) } 復制代碼使用
const newBind = require("./bind") const newCall = require("./call") const newApply = require("./apply")Function.prototype.newBind = newBind //將bind掛載到Function原型,使得任何實例可以像使用bind一般使用newBind Function.prototype.newCall = newCall //將call掛載到Function原型,使得任何實例可以像使用call一般使用newCall Function.prototype.newApply = newApply //將apply掛載到Function原型,使得任何實例可以像使用apply一般使用newApply 復制代碼在掛載到原型上后,就可以正常使用了
測試
1、bind的測試
require(".") //導入模塊const obj = {q: "1" }const Parent = function(a, b){this.a = a;this.b = b }//一、使用bind的函數是構造函數,context是有效對象 //測試bind帶參,執行函數不帶參的情況 try {console.log(Parent.newBind(obj,3,2)()) } catch (error) {if(error.toString()=="Illegal context") console.log("err")else console.log("Failed") }//測試bind帶參,執行函數帶參的情況 => 執行函數的參數不生效 try {console.log(Parent.newBind(obj,3,2)(3,4)) } catch (error) {if(error.toString()=="Illegal context") console.log("err")else console.log("Failed") }//測試bind不帶參的情況,執行函數不帶參的情況 => 執行函數的參數應為undefined try {console.log(Parent.newBind(obj)()) } catch (error) {if(error.toString()=="Illegal context") console.log("err")else console.log("Failed") }//測試bind帶參,執行函數帶參的情況 => 執行函數的帶參應生效 try {console.log(Parent.newBind(obj)(3,4)) } catch (error) {if(error.toString()=="Illegal context") console.log("err")else console.log("Failed") }//二、使用bind的函數是構造函數,context是無效對象 //測試bind帶參,執行函數不帶參的情況 console.log(Parent.newBind(null,3,2)())//測試bind帶參,執行函數帶參的情況 console.log(Parent.newBind(null,3,2)(3,4))//測試bind不帶參的情況,執行函數不帶參的情況 console.log(Parent.newBind(null)())//測試bind帶參,執行函數帶參的情況 console.log(Parent.newBind(null)(3,4))//三、使用bind的函數不是構造函數 console.log(Math.pow.newBind(obj, 3, 2)()) console.log(Math.pow.newBind(null, 3, 2)()) console.log(Math.pow.newBind(1, 3, 2)()) console.log(Math.pow.newBind(null)(2,3))console.log("測試完成") 復制代碼2、call的測試
require(".") //導入模塊const obj = {q: "1" }const Parent = function(a, b){this.a = a;this.b = b }//一、使用call的函數是構造函數,context是有效對象 //測試call帶參 try {console.log(Parent.newCall(obj,3,2)) } catch (error) {if(error.toString()=="Illegal context") console.log("err")else console.log("Failed") }//測試call不帶參的情況 => 執行函數的參數應為undefined try {console.log(Parent.newCall(obj)) } catch (error) {if(error.toString()=="Illegal context") console.log("err")else console.log("Failed") }//二、使用call的函數是構造函數,context是無效對象 //測試call帶參 console.log(Parent.newCall(null,3,2))//測試call不帶參的情況 console.log(Parent.newCall(null))//三、使用call的函數不是構造函數 console.log(Math.pow.newCall(obj, 3, 2)) console.log(Math.pow.newCall(null, 3, 2)) console.log(Math.pow.newCall(1, 3, 2))console.log("測試完成") 復制代碼3、apply的測試
require(".") //導入模塊const obj = {q: "1" }const Parent = function(a, b){this.a = a;this.b = b }//一、使用apply的函數是構造函數,context是有效對象 //測試apply帶參 try {console.log(Parent.newApply(obj,[3,2])) } catch (error) {if(error.toString()=="Illegal context") console.log("err")else console.log("Failed") }//測試apply不帶參的情況 => 執行函數的參數應為undefined try {console.log(Parent.newApply(obj)) } catch (error) {console.log(error);if(error.toString()=="Illegal context") console.log("err")else console.log("Failed") }//二、使用apply的函數是構造函數,context是無效對象 //測試apply帶參 console.log(Parent.newApply(null,[3,2]))//測試apply不帶參的情況 console.log(Parent.newApply(null))//三、使用apply的函數不是構造函數 console.log(Math.pow.newApply(obj, [3, 2])) console.log(Math.pow.newApply(null, [3, 2])) console.log(Math.pow.newApply(1, [3, 2])) console.log(Math.pow.newApply(1, 3, 2)) //第二個參數不為數組,結果應異常console.log("測試完成") 復制代碼經過測試,實現call、apply、bind基本功能是ok的
github地址
源碼
轉載于:https://juejin.im/post/5d063083f265da1ba9157c8b
總結
以上是生活随笔為你收集整理的面试题:实现call、apply、bind的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JDK源码分析-TreeMap(1)
- 下一篇: LR关于数据加密