据我所知,在javascript中有三个概念;呼叫,申请和绑定 我想用类似的行为创建这些功能。
答案 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函数有多少:
有关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));
}