介绍一下call,apply,bind方法实现,源于MDN中的bind
首先看一下call方法
Function.prototype.MyCall = function(thisObj){
console.log(thisObj) // 这里面就是实例化对象
console.log(this) //这里面就是Cluster
let obj = {}
obj = thisObj || window
const args = [...argument].slice(1)
obj.fn = this
let result = obj.fn(...args)
delete obj.fn
return result
}
Function.prototype.myCall = function(ctx,...args){
ctx = ctx === null || ctx === undefined ? globalThis : Object(ctx);
const fn = this
const key = Symbol()
Object.defineProperty(ctx,key,{
value:fn,
enumerable:true
})
const r = ctx[key](...args)
delete ctx[key]
return r
}
function Person(){
this.name = 'bai'
Cluster.MyCall(this)
}
function Cluster(){
this.name = 'cluster'
this.action = function(){
return '吃饭'
}
}
const person = new Person()
console.log(person.action())
//我们想想call,apply的区别无非就是第二参数一个是数组(apply),另一个不是
只要将obj.fn这改为obj.fn(Array.from(args))
let slice = Array.prototype.slice; Function.prototype.bind = function () { let Func = this, that = arguments[0]; let args = slice.call(arguments, 1); return function () { var funcArgs = args.concat(slice.call(arguments)); return Func.apply(that, funcArgs); }; };
function output(...s){
console.log(this,s)
}
output.bind(123,'EE','DD')(1,2,3)
</script>
介绍下栈溢出
function sum(x, y) {
if (y > 0) { return sum(x + 1, y - 1); } else { return x; }}sum(1, 100000000000)
这个时候会出现一个堆栈溢出的错误,在es6里面,有一个为递归优化的方法可以解决,即在最后一步调用函数,且实现函数的柯里化(多参函数转换成单参数函数),但是需要开启严格模式,普通模式下会报错,这个时候我再阮大神的es6书籍里面,看到了蹦床函数,结合.bind,使函数调用的时候是自己的方法,但是确是另一个函数对象,不是本身,这个时候就不会造成内存的泄露,发生堆栈溢出了,实现代码如下:
function trampoline(f) {
while (f && f instanceof Function) { f = f(); } return f;}function sum(x, y) {
if (y > 0) { return sum.bind(null, x + 1, y - 1); } else { return x; }}trampoline(sum(1, 100000))

浙公网安备 33010602011771号