在对象文字上调用函数,由字符串 - JavaScript 表示

Call function on object literal, represented by string - JavaScript

本文关键字:字符串 JavaScript 表示 对象 文字上 调用 函数      更新时间:2023-09-26

我正在使用历史记录.js。在 pushState 函数的 stateObj 中,我想添加一个对函数的引用(Car.init()Boat.init() 。 在C++中,我相信我可以使用函数指针。

然后在window.onpopstate上,我想引用该函数并调用它。 我可以读取字符串(Car.init(),但是我该如何调用该函数呢? 我不想使用eval.

您可能不应该这样做,但是如果您确实想调用基于全局虚线路径名称的函数,则可以像这样完成:

function callFunction(name, var_args) {
  // break the string into individual property/method names
  var parts = name.split('.');
  // start with a reference to the global object
  var target = window;
  var previousTarget = null;
  for (var i = 0; i < parts.length; i++) {
    // keep a copy of the previous reference to use as the `this` value
    previousTarget = target;
    // change the reference to the next named property
    target = target[parts[i]];
  }
  // grab the remaining arguments
  var args = Array.prototype.slice.call(arguments, 1);
  // call the target function, with previousTarget as the subject, using args
  return target.apply(previousTarget, args);
}
// This is in the top-level/global scope. This won't work for a local definition.
var MyApp = {
  currentUser: {
    name: 'Joe',
    displayName: function(greeting) {
      alert(greeting + " ," + this.name + "!");
    }
  },
  openBar: function() {
    alert("The Foo Bar is now open for business!");
  }
};
var functionName = 'MyApp.currentUser.displayName';
callFunction(functionName, "Hello");

这比使用eval更安全(避免它的好要求),但仍然非常古怪,并且对于JavaScript解释器来说很难优化。相反,建议的方法是使用对函数的引用(指针)。这可能类似于您在C++中所做的。如果函数不使用this(即,如果它是一个静态函数,而不是一个方法),你可以直接引用该函数。

var open = MyApp.openBar;
open();

如果它确实具有this值,则需要使用 .bind() 方法来保留其与附加到对象的关联。

var display = MyApp.currentUser.displayName.bind(MyApp.currentUser);
display("Greetings");

如果将其他参数传递给 .bind() ,还可以指定将用于调用函数的前导参数。

var displayHello = MyApp.currentUser.displayName.bind(MyApp.currentUser, "Hello");
displayHello();