簡體   English   中英

從JavaScript中的對象調用具有正確參數的函數

[英]Invoke a Function with the Correct Parameters from an Object in JavaScript

假設我有一個看起來像這樣的對象:

{
     'apple': 'nice',
     'banana': 'decent',
     'cherry': 'yuck',
}

我有兩種方法:

function eatItems(cherry, apple) { }
function throwItem(banana) { }

我的兩個問題:

  1. 我可以調用eatItem並以正確的順序發送參數嗎? 也許像這樣:

    eatItems.call(this,{'cherry':cherry,'apple':apple});

  2. 如果我不知道eatItems接收什么參數,該如何動態地查詢一個函數的參數名稱,以便知道將它們放入的順序?

確實有一種方法,它涉及到在函數上調用toString

var source = eatItems.toString();
// => "function eatItems(cherry, apple) { }"

下一步是解析要獲取參數名稱的字符串:

var args = source.substring(source.indexOf("(") + 1, source.indexOf(")")),
    argNames = /\S/.test(args) ? args.split(/\s*,\s*/) : [];

一些警告:

  1. 該解決方案一直保持非常簡單。 它不處理函數定義中的注釋。
  2. 並不是每個瀏覽器都能正確地將函數轉換為字符串(我想到了PS3瀏覽器),但是無論如何它們只是很小的一部分。
  3. 我尚未對其進行測試,但是在速度較慢的計算機和/或功能較舊的舊版瀏覽器上可能存在一些性能問題。

總體而言,此解決方案更像是一種練習。 我不建議在Javascript中采用這種模式。 別忘了有些函數處理可變數量的參數,並且您不會在它們的定義中找到它們。 重新考慮您的代碼,並找到更好的方法。

如果我理解正確,則需要從函數中提取參數名稱,並基於這些名稱從對象中注入數據。 這可以通過將函數轉換為字符串,提取參數並使用帶有這些參數的函數來實現:

function inject(data, f) {
  var args = f.toString()
    .match(/function\s*?\((.+?)\)/)
    .pop()
    .split(',')
    .map(function(a){return data[a.trim()]})
  return function() {
    return f.apply(this, args)
  }
}

var data = {
  apple: 'nice',
  banana: 'decent',
  cherry: 'yuck',
}

var eat = inject(data, function(cherry, apple) {
  console.log(cherry, apple)
})

eat() //=> yuck, nice

這種方法的明顯問題是它高度依賴於變量名,因此,當您壓縮代碼時,變量將被弄亂,函數將停止工作。 這是AngularJS中的一個已知問題,它對依賴項注入使用了類似的方法。

這通常是XY問題,或者至少是反圖案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM