2014-01-07 46 views
0

我知道javascript函數可以接受任意數量的參數,可以通過arguments[i]訪問。我想知道是否可以將該數組轉換爲單獨的參數以發送到另一個函數,該函數也處理變量列表的參數。是否可以將字符串列表轉換爲變量列表的參數?

我對字符串類的基本格式類似於string.format()在.Net中的工作方式。

String.prototype.format = String.prototype.format = function() { 
    var s = this, 
     i = arguments.length; 

    while (i--) { 
     s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]); 
    } 
    return s; 
}; 

我有另一個功能,需要一個javascript對象,併發送屬性來處理成一個字符串。這些屬性由調用函數設置。這是我試圖獲得的用法的一個例子。我只是簡單地將屬性作爲單個參數傳遞給上面的函數。關於如何實現這個的任何想法?

function doMything(){ 

    var myData = GetMyDataFromSomething(); // returns a javascript array of objects 
    var myMessageFormat1 = 'Person with ID {0} name is {1} {2}'; 
    var myPropertyList1 = ['UserID', 'FirstName', 'LastName'] 

    var finishedStrings1 = formatTheString(myData, myMessageFormat1, myPropertyList1); 
    // ex. Person with ID 45 name is Jake Gyllenhal; Person with ID 46 name is Bob Barker 

    var myMessageFormat2 = '{0} is from {1}, {2}'; 
    var myPropertyList2 = ['FirstName', 'City', 'State'] 

    var finishedStrings2 = formatTheString(myData, myMessageFormat2, myPropertyList2); 
    // ex. Jake is from Phoenix, AZ; Bob is from San Diego, CA 
} 

function formatTheString(data, formatString, propertyList){ 
     var myStrings = []; 
     data.forEach(function(item){ 
      myStrings.push(item.format(propertyList)); // this doesn't work because the object is passed as a single argument 
     }; 

     return myStrings.join('; '); 
} 
+1

'anotherfunction.apply(context,arguments);'---這是你想要的嗎? – zerkms

+1

「」.format很快就會出現,我會用不同的名字...... – dandavis

+0

@dandavis好點。我將重新命名爲formatText,直到字符串格式化標準化。 – Sinaesthetic

回答

0

使用apply(see MDN)

var yourArguments = ['foo', 'bar']; 

formatString.format.apply(formatString, yourArguments); 
// equivalent to 'formatString.format('foo', 'bar') 

所以,你的功能可能是:

function formatTheString(data, formatString, propertyList){ 
     var myStrings = []; 
     data.forEach(function(item){ 
      myStrings.push(item.format.apply(item, propertyList)); 
     }; 

     return myStrings.join('; '); 
} 
0

肯定。使用apply()

var args = ['arg1', 'arg2']; 
    fn.apply(this, args); 

相當於

fn('arg1', 'arg2'); 
+2

不知道爲什麼這是低票,我的猜測是,這是因爲這兩個在技術上不相同。使用'apply'可以讓你指定'this'上下文,這裏你已經爲調用者設置了'this'。然而,從作用域(相對於對象的屬性)調用函數將具有'this'指向'window'(全局對象)。 – Peter

3

其他的答案是正確的,但只是爲了明確顯示arguments鏈:

function one() { 
    two.apply(this, arguments); 
} 

function two() { 
    console.log(arguments); 
} 

one("one", "two", "three"); 

打印:

["one", "two", "three"] 
0

我只是想添加這個作爲我最終的工作解決方案,希望它能幫助別人。在我的原始思想中有一些邏輯錯誤。

var MyClass = { 

    loadSupportArticles: function() { 
      var itemMarkupFormat = '<tr class="row-link single-cell"><td><a href="support-page.html/{0}">{1}</a></tr>'; 
      var $supportAriclesList = $('#support-panel tbody'); 

      this.populateTableFromAjaxResult(
       '/support/Popular', 
       $supportAriclesList, 
       itemMarkupFormat, 
       ['ArticleId', 'Title']); 
     }, 

    loadUsers: function() { 
      var itemMarkupFormat = '<tr class="row-link"><td><a href="edit-user.html/{0}">{1}</a></td><td>{2}</td></tr>'; 
      var $userSummaryList = $('#users-panel tbody'); 

      this.populateTableFromAjaxResult(
       '/accountuser/AccountUsersAsync', 
       $userSummaryList, 
       itemMarkupFormat, 
       ['Id', 'Name', 'Type']); 
     }, 

    // the part you guys helped with 
    getListItems: function(data, formatString, propertyNames) { 
     var completeList = []; 

     // for each data item 
     for (var i = 0; i < data.length; i++) { 

      // get values for each argument 
      var args = []; 
      for (var j = 0; j < propertyNames.length; j++) { 
       var propertyName = propertyNames[j]; 
       args.push(data[i][propertyName]); // e.g. data[0]["PropName"] 
      } 

      // apply the template 
      completeList.push(formatString.format.apply(formatString, args)); 
     } 

     return completeList.join(''); 
    }, 

    populateTableFromAjaxResult: function(url, $target, formatString, propertyNames) { 
     $target.empty(); 

     $.ajax({ 
      url: url, 
      type: 'GET', 
      accept: 'application/json', 
      success: function(data) { 
       var formattedData = MyClass.getListItems(data, formatString, propertyNames); 
       $target.append(formattedData); 
      } 
     }); 
    } 
}