如何在 javascript 中创建自己的调用函数?
How can create own call function in javascript?
据我所知,javascript中有三个概念;调用、申请和绑定
我想创建具有类似行为的这些函数。
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)
我按照这种方法创建了自己的调用函数。在 Function Constructor 的帮助下,我向它添加了一个函数,它在 firefox 上运行。
这是他们的 polyfill(虽然不准确,只是我想到的):
Function.prototype.call = function(context, ...args) {
const fn = Symbol();
try {
context[fn] = this;
return 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;
}
return context[fn](...args);
};
Function.prototype.apply = function(context, args) {
return this.call(context, ...args);
};
Function.prototype.bind = function(context, ...args) {
return (...args2) => this.call(context, ...args, ...args2);
};
唯一无法填充的是 fn.call(null)
,因为无法将原语转换为复杂类型,只有本机代码可以做到这一点
添加您自己的调用函数,如“_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)
}
像以前一样称呼它。第一个参数应该是一个对象。不然写个代码把它转成object。
anyfunction._call({'mm':'my provided this object'},"arg1","arg2")
虽然每个浏览器都有自己的实现 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
这是我的甜蜜而简单的解决方案。我们正在原型链中添加 ObjRef 以避免与其他属性发生任何名称冲突
Function.prototype.call2 = function (objRef, ...args) {
otherObj = Object.create(objRef)
otherObj[this.name] = this;
otherObj[this.name](...args);
}
在上面的答案中我可以看到已经使用了传播运算符,但是如果我们真的想对调用进行 pollyfill 那么我们应该避免传播
es6.I 的运算符和最新概念正在分享没有 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));
}
我认为在这里使用 Object.create
没有意义,因为当您在函数中使用 this
时,您将看不到所需的对象。
这是我的尝试(虽然不准确)但会起作用。
Function.prototype.myCall = function (thisContext, ...param) {
let name = this.name;
thisContext[name] = this;
thisContext[name](...param);
}
据我所知,javascript中有三个概念;调用、申请和绑定 我想创建具有类似行为的这些函数。
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)
我按照这种方法创建了自己的调用函数。在 Function Constructor 的帮助下,我向它添加了一个函数,它在 firefox 上运行。
这是他们的 polyfill(虽然不准确,只是我想到的):
Function.prototype.call = function(context, ...args) {
const fn = Symbol();
try {
context[fn] = this;
return 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;
}
return context[fn](...args);
};
Function.prototype.apply = function(context, args) {
return this.call(context, ...args);
};
Function.prototype.bind = function(context, ...args) {
return (...args2) => this.call(context, ...args, ...args2);
};
唯一无法填充的是 fn.call(null)
,因为无法将原语转换为复杂类型,只有本机代码可以做到这一点
添加您自己的调用函数,如“_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)
}
像以前一样称呼它。第一个参数应该是一个对象。不然写个代码把它转成object。
anyfunction._call({'mm':'my provided this object'},"arg1","arg2")
虽然每个浏览器都有自己的实现 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
这是我的甜蜜而简单的解决方案。我们正在原型链中添加 ObjRef 以避免与其他属性发生任何名称冲突
Function.prototype.call2 = function (objRef, ...args) {
otherObj = Object.create(objRef)
otherObj[this.name] = this;
otherObj[this.name](...args);
}
在上面的答案中我可以看到已经使用了传播运算符,但是如果我们真的想对调用进行 pollyfill 那么我们应该避免传播 es6.I 的运算符和最新概念正在分享没有 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));
}
我认为在这里使用 Object.create
没有意义,因为当您在函数中使用 this
时,您将看不到所需的对象。
这是我的尝试(虽然不准确)但会起作用。
Function.prototype.myCall = function (thisContext, ...param) {
let name = this.name;
thisContext[name] = this;
thisContext[name](...param);
}