如何在javascript中创建自己的调用函数?

时间:2018-07-24 16:51:59

标签: javascript function call

据我所知,在javascript中有三个概念;呼叫,申请和绑定 我想用类似的行为创建这些功能。

6 个答案:

答案 0 :(得分:2)

function B(a,b,c){
   console.log(a,b,c)
}

Function.prototype.OwnCallFunction = function(){  
    if( this.length == arguments.length)
        this(...arguments)
    else
        console.error('Signature does not match')
 } 
B.OwnCallFunction(323,34,34)

我遵循了这种方法来创建自己的调用函数。在函数构造器的帮助下,我向其中添加了一个函数,该函数可以在Firefox中使用。

答案 1 :(得分:2)

这对他们来说是一个填充(虽然不准确,只是我想到的):

Function.prototype.call = function(context, ...args) {
  const fn = Symbol();
  try {
    context[fn] = this;
    context[fn](...args);
   } catch(e) {
      // Turn primitive types into complex ones 1 -> Number, thanks to Mark Meyer for this.
     context = new context.constructor(context);
     context[fn] = this;
     context[fn](...args);
  }
};

Function.prototype.apply = function(context, args) {
  this.call(context, ...args);
};

Function.prototype.bind = function(context, ...args) {
  return (...args2) => this.call(context, ...args, ...args2);
};

唯一无法填充的是fn.call(null),因为该原语无法转换为复杂类型,只有本机代码才能做到这一点

答案 2 :(得分:2)

添加您自己的调用函数,例如“ _call”

Function.prototype._call = function(newcontext, ...arg){

var demoFn = new Function('tempfuncton', 'tempthis','arg' , '{ tempthis["f"]=tempfuncton; return tempthis.f(arg);}');
demoFn(this,newcontext,arg);
}

编写演示功能

function anyfunction(args){
console.log(this,args)
}

像以前一样称呼它。第一个参数应该是一个对象。否则,编写代码将其转换为对象。

anyfunction._call({'mm':'my provided this object'},"arg1","arg2")

答案 3 :(得分:0)

尽管每个浏览器都有自己的用于实现Javascript的源代码,但是您可以找到使用ECMA规范实现的本机Javascript函数有多少:

http://www.ecma-international.org/ecma-262/10.0/index.html#sec-properties-of-the-function-prototype-object

有关apply的规格,请参见:19.2.3.1

有关bind的规格,请参见:19.2.3.2

有关call的规格,请参阅:19.2.3.3

例如,如果您对Node如何实现apply感兴趣,可以在以下Github上挖掘其源代码:https://github.com/nodejs/node

答案 4 :(得分:0)

这是我最简单的解决方案。我们在原型链中添加了ObjRef,以避免与其他属性发生名称冲突

    Function.prototype.call2 = function (objRef, ...args) {
      otherObj = Object.create(objRef)
      otherObj[this.name] = this;
      otherObj[this.name](...args);
    }

答案 5 :(得分:0)

在上面的答案中,我可以看到已经使用了扩展运算符,但是如果我们真的想对调用进行 pollyfill 那么我们应该避免扩展 运营商和es6的最新概念。我正在分享没有es6的解决方案。

调用函数:-

Function.prototype.myCall = function(obj) {
   obj = obj || global;
   var id = "00" + Math.random();
  while (obj.hasOwnProperty(id)) {
    id = "00" + Math.random();
  }
  obj[id] = this;
  let arg=[];
  for(let i=1;i<arguments.length;i++){
       arg.push("arguments[" + i + "]");
  }
 result= eval("obj[id]("+arg+")");
  delete obj[id];
  return result;
}

应用功能:-

Function.prototype.myApply = function(obj, argArr) {
 obj = obj || global;
 var id = "00" + Math.random();
 while (obj.hasOwnProperty(id)) {
  id = "00" + Math.random();
 }
 obj[id] = this;
 let arg=[];
 let result
 if(!argArr){
  result= obj[id].fn();
 }
 else{
  for(let i=0;i<argArr.length;i++){
      arg.push("argArr[" + i + "]");
     }
  result= eval("obj[id]("+arg+")");
  delete obj[id];
}
return result;

}

绑定函数:-

Function.prototype.myBind2= function(){
  let obj1= this;
  const obj= Array.prototype.slice.call(arguments,0,1);
   const arg= Array.prototype.slice.call(arguments,1);
  return function(){
    const arg2= Array.prototype.slice.call(arguments);
   obj1.apply(obj[0],Array.prototype.concat(arg, arg2));
}

另一个解决方案绑定:我们可以传递函数的对象参数

Function.prototype.myBind2 = function(obj) {
  let fn = this;
  const arg = Array.prototype.slice.call(arguments, 1);
  return function() {
    const arg2 = Array.prototype.slice.call(arguments);
    fn.apply(obj, Array.prototype.concat(arg, arg2));
  }