Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

用代码模拟出apply()、call()和bind()三个函数。 #854

Open
pwstrick opened this issue Jul 18, 2019 · 2 comments
Open

用代码模拟出apply()、call()和bind()三个函数。 #854

pwstrick opened this issue Jul 18, 2019 · 2 comments
Labels
JavaScript JavaScript类的题目

Comments

@pwstrick
Copy link
Owner

pwstrick commented Jul 18, 2019

用代码模拟出apply()、call()和bind()三个函数。

参考《20道JS原理题助你面试一臂之力!

@pwstrick pwstrick added the JavaScript JavaScript类的题目 label Jul 18, 2019
@pwstrick pwstrick changed the title 用代码实现apply()函数和call()函数。 用代码模拟出apply()、call()和bind()三个函数。 Jul 18, 2019
@pwstrick
Copy link
Owner Author

pwstrick commented Jun 12, 2020

Function.prototype.myCall = function(context) {
  context.fn = this;
  let args = []
  for(let i=1; i<arguments.length; i++) {
    args.push(arguments[i]);
  }
  const result = context.fn(...args);
  delete context.fn;
  return result;
}

Function.prototype.myBind= function (context) {
    var self = this;
    var args = [].slice.call(arguments, 1);

    var fBound = function () {
        var bindArgs = [].slice.call(arguments);
        // 当作为构造函数时,this 指向实例,此时结果为 true,将绑定函数的 this 指向该实例,可以让实例获得来自绑定函数的值
        // 以上面的是 demo 为例,如果改成 `this instanceof fBound ? null : context`,
        // 实例只是一个空对象,将 null 改成 this ,实例会具有 habit 属性
        // 当作为普通函数时,this 指向 window,此时结果为 false,将绑定函数的 this 指向 context
        return self.apply(this instanceof fBound ? this : context, args.concat(bindArgs));
    }
    // 修改返回函数的 prototype 为绑定函数的 prototype,实例就可以继承绑定函数的原型中的值
    fBound.prototype = this.prototype;
    return fBound;
}

参考《JavaScript深入之call和apply的模拟实现》《JavaScript深入之bind的模拟实现

@lisonge
Copy link

lisonge commented Apr 4, 2021

该代码会在以下情况下失效

function test(){
return this.length;
}

test.myCall('hello); // error

const obj = {length:4399};
Object.freeze(obj);
// or
Object.seal(obj);

test.myCall(obj); // error

apply call bindnative 层级的,是无法用 纯 js 去实现的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JavaScript JavaScript类的题目
Projects
None yet
Development

No branches or pull requests

2 participants