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

时间:2017-03-08 02:54:52

标签: javascript function

是否可以在Javascript中调用1函数时调用分配给它的多个函数?

以下是我想要做的事情:

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;

但我希望看看第一个是否可以选择查看可能的语法/用例。

谢谢!

2 个答案:

答案 0 :(得分:1)

<强>更新

我已经编写了一个更抽象的语法来实现相同的功能。请查看上一个答案进行解释。

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();

如果这解决了你想要做的事情,或者你在这里什么都不懂,请告诉我。

答案 1 :(得分:1)

如果你只是寻找语法糖,那么我不知道那样的东西。 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"

如果您想为各个玩家设置功能,请使用Player的实例

class Player {

  constructor () {
    this._logFunctions = []
  } 

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

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

}

也许看看ES2015 Proxy对象。它允许您修改目标对象行为,这在同一个球场中但可能不适用于此处。