面试题十九:手写call()、apply()和bind()
七娃博客1,640人阅读
要想实现手写call,必须知道call()这个函数的定义,如何使用?有什么特点?
call
call()定义
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
call()语法
function.call(thisArg, arg1, arg2, ...)
-
thisArg,this指向,可以省略!
-
arg1...参数
手写call()
知道了call的定义和特点,就可以来实现其方法了,另外call是在function函数的原型上:
Function.prototype.mycall = function(content){ if(typeof this != 'function'){ throw new TypeError('this is not a function') } let ctx = content || window // 未传值时指向window ctx.fn = this // 找到调用的方法 let args = Array.from(arguments).slice(1) // 拷贝参数 let res = args ? ctx.fn(...args) : ctx.fn() // 创建一个 新对象,改变this指向 delete ctx.fn // 删除 上下文 避免全局污染 return res }
同样的,要想实现手写apply,必须知道apply()这个函数的定义,如何使用?有什么特点?
apply
apply()定义
apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。
apply()语法
function.apply(thisArg, [argsArray])
-
thisArg,this指向,可以省略!
-
[argsArray],数组参数
手写apply()
根据apply的特点,就可以实现一个apply了:
Function.prototype.myApply = function(content){ if(typeof this != 'function'){ throw new TypeError('this is not a function') } let ctx = content || window // 未传值时指向window ctx.fn = this // 找到调用的方法 let args = arguments[1] // 拷贝参数 let res = args ? ctx.fn(...args) : ctx.fn() // 创建一个 新对象,改变this指向 delete ctx.fn // 删除 上下文 避免全局污染 return res }
apply和call很像,就是传参不一样,所以手写的函数也是 拷贝参数的方法不一样! 最后一个bind,和这两个不一样!
bind
bind()定义
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
bind()语法
function.bind(thisArg[, arg1[, arg2[, ...]]])
- thisArg,this指向,可以省略!
- arg1...参数
手写bind()
Function.prototype.myBind = function(content){ if(typeof this != 'function'){ throw new TypeError('this is not a function') } let that = this; let args = Array.prototype.slice.call(arguments,1); let Fn = function(){} Fn.prototype = this.prototype; let binds = function(){ let bindArgs = Array.prototype.slice.call(arguments); return that.apply(this instanceof Fn ? this : content,args.concat(bindArgs)) } binds.prototype = new Fn(); return binds; }
评论 | 0 条评论
登录之后才可留言,前往登录