有没有办法在Javascript中为多个函数分配一个函数?

问题描述:

是否可以在JavaScript中使用,当1个函数被调用时,它会调用分配给它的多个函数?有没有办法在Javascript中为多个函数分配一个函数?

下面是我想做的事:

var player1= {name: "Chris", score: 1000, rank: 1}; 
var player2= {name: "Kristofer", score: 100000, rank: 2}; 

function playerDetails(){ 
alert("The name of the player is "+ this.name + "."+ " His score is : "+ this.score + "and his rank : "+ this.rank); 
} 

function playerDetailsSecond() 
{ 
//Do something else 
} 

player1.logDetails= playerDetails; 
player2.logDetails= playerDetails; 

//Is it possible to do this? 
player1.logDetails += playerDetailsSecond; 
player2.logDetails += playerDetailsSecond; 

player1.logDetails(); //calls both playerDetails and playerDetailsSecond 
player2.logDetails(); //calls both playerDetails and playerDetailsSecond 

的+ =特别是我想做的事情。

我认识一个选择是像做:

function combined() 
{ 
playerDetails(); 
playerDetailsSecond(); 
} 

player1.logDetails = combined; 

但我希望能看到,如果第一个是看有可能的语法/使用情况的选项。

谢谢!

+1

'+ ='不会像那样工作。你试图解决什么问题?你是否有很多玩家需要附加多个功能?球员之间的功能会有所不同吗? – Matt

+0

我正在使用ChakraBridge将.NET类公开到Javascript中。在这种情况下,LogDetails实际上是.NET中的一个事件,我在.NET中使用+ =订阅。我希望Javascript有类似的东西,但可能是一种不同的语法。 LogDetails = playerDetails确实有效(例如在.NET中引发事件,Javascript函数被调用),但是我想知道如果我想运行订阅该事件的多个函数? – Water

+0

为什么不使用回调或承诺,在'playerDetails()'之后运行'playerDetailsS​​econd()'? – shole

我写了一个更抽象语法更新实现相同。看以前的答案解释。

var player1 = { name: "Chris", score: 1000, rank: 1 }; 

function playerDetails(arg1, arg2) { 
    console.log("The name of the player is " + this.name + "." + " His score is : " + this.score + "and his rank : " + this.rank + arg1 + arg2); 

    //make sure you add this line at the end 
    arguments.callee.invokeExtras(this, arguments); 
} 


//you do not need to look into this code. 
// this code adds functionality of pushing extra functions. 
playerDetails.addFunction = function(fn) { 
    this.extraFns?this.extraFns.push(fn):this.extraFns = [fn]; 
} 
playerDetails.invokeExtras = function(context, args) { 
    this.extraFns?this.extraFns.forEach(function(fn) { fn.apply(context, args) }):null; 
} 
//upto here 

function playerDetailsSecond(arg1, arg2) { 
    console.log("The name of the player is " + this.name + arg1 + arg2); 
} 

function playerDetailsThird(arg1, arg2) { 
    console.log("new extra funtion " + this.name + arg1 + arg2); 
} 


player1.logDetails = playerDetails; 

player1.logDetails.addFunction(playerDetailsSecond); 
player1.logDetails.addFunction(playerDetailsThird); 

player1.logDetails("test1", "test2"); 

以前的答案

这是如何实现这一点。 这里的概念是将函数视为第一类对象,这意味着函数可以具有属性。

现在第一个函数将在最后有两个额外的行。

var self = this; 
arguments.callee.extraFns.forEach(function (extraFunction) { extraFunction.call(self) }); 

和函数的声明之后,你需要一个空数组extraFns添加到函数。

下面是完整的代码:

var player1 = { name: "Chris", score: 1000, rank: 1 }; 

function playerDetails() { 
    console.log("The name of the player is " + this.name + "." + " His score is : " + this.score + "and his rank : " + this.rank); 

    var self = this; 
    arguments.callee.extraFns.forEach(function (extraFunction) { extraFunction.call(self) }); 
} 

playerDetails.extraFns = []; 

function playerDetailsSecond() { 
    console.log("The name of the player is " + this.name); 
} 

function playerDetailsThird() { 
    console.log("new extra funtion " + this.name); 
} 


player1.logDetails = playerDetails; 

player1.logDetails.extraFns.push(playerDetailsSecond); 
player1.logDetails.extraFns.push(playerDetailsThird); 

player1.logDetails(); 

让我知道如果这能解决你想要做什么,或者,如果你不明白这里什么。

+0

感谢pranav,它的工作原理!最后一个问题,如果我在子函数上也有一些参数呢? – Water

+0

欢迎! 你所有的功能需要有相同数量的参数,你可以将它们传递给extraFunction.call(self,a,b,c ..) 另外。你可以upvote并接受答案。 :) – pranavjindal999

+0

太棒了!感谢那。 – Water

如果你只是在寻找语法糖,那么我不知道这样的事情。 Array.push()可能是将通用对象附加到某些东西的最短途径。

最简单的方法是根据您的建议调用多个函数。如果您将该功能附加到Player课程,则所有玩家将继承相同的功能。

class Player { 

    logDetails() { 
    function1(arguments) 
    function2(arguments) 
    } 

} 

如果您正在寻找以编程方式添加的功能,那么你可以实现对Player类的东西。

所有玩家

class Player { 

    static addLogFn (fn) { 
    this.logFunctions.push(fn) 
    } 

    logDetails() { 
    for (let fn of this.constructor.logFunctions) { 
     fn.apply(this, arguments) 
    } 
    } 

} 
Player.logFunctions = [] 

let player1 = new Player() 
player1.name = 'meee' 
player1.rank = 'peon' 
Player.addLogFn(function(arg){console.log(this.name, arg)}) 
player1.logDetails('a') // => "meee a" 
Player.addLogFn(function(arg1, arg2){console.log(this.rank, arg2)}) 
player1.logDetails('b','c') // => "meee b\npeon c" 

或者,如果你想设置的功能个别球员

class Player { 

    constructor() { 
    this._logFunctions = [] 
    } 

    logDetails() { 
    for (let fn of this._logFunctions) { 
     fn(arguments) 
    } 
    } 

    addLogFunction (fn) { 
    this._logFunctions.push(fn) 
    } 

} 

也许看ES2015 Proxy对象也使用播放器的实例。它允许你修改一个目标对象的行为,这是在同一个球场,但可能不适用在这里。