2011-10-05 22 views
5

thể trùng lặp:
Use of .apply() with 'new' operator. Is this possible?Sử dụng áp dụng với một constructor function

Tôi có 5 hoặc 6 bài tập biến dạng

var analyteSelection = new TemplatedSelectionContainer($('.analyte-container', this), helpers, optionsTemplate); 
var instrumentSelection = new AssetBackedSelection($('.instrument-container', this), helpers, optionsTemplate, Assets.instruments, 'Instrument'); 
var methodSelection = new AssetBackedSelection($('.method-container', this), helpers, optionsTemplate, Assets.methods, 'Method'); 

Như bạn có thể thấy, một số lượng đáng kể phần của các nhà xây dựng này rất giống nhau. Nó sẽ được tốt đẹp nếu tôi có thể tạo ra một chút builder currying generic mà sẽ cho phép tôi làm điều gì đó như:

var newSel = selectionContainerBuilder(this, helpers, optionsTemplate) 
var analyteSelection = newSel(TemplatedSelectionContainer, '.analyte-container'); 
var instrumentSelection = newSel(AssetBackedSelection, '.instrument-container', Assets.instruments, 'Instrument'); 
var methodSelection = newSel(AssetBackedSelection, '.method-container', Assets.methods, 'Method'); 

tôi có thể đạt được một cái gì đó tương tự với

var selectionContainerBuilder = function(ctx, helpers, optionsTemplate) { 
    return function(FuncDef, selector, a, b, c, d, e, f) { 
    return new FuncDef($(selector, ctx), helpers, optionsTemplate, a,b,c,d,e,f); 
    } 
} 

Nhưng nghiêm túc ick. Tôi muốn chỉ có thể ghép ba thông số đầu tiên được biết đến vào đầu của mảng đối số và áp dụng nó cho FuncDef nhưng tôi đang bị hư hỏng bởi sự cần thiết phải sử dụng toán tử mới.

Và trước khi người nào đó hỏi, tôi không thể thực hiện thao tác điều hành mới bên trong FuncDef vì nó được tạo bởi từ khóa lớp coffeescript.

Trả lời

3

Tất nhiên nó có thể được thực hiện. Đây là trường hợp mà eval hóa ra là hữu ích.

function newApply(cls, args) { 
    var argsAsString = []; 
    for (var i = 0, l = args.length; i < l; i++) { 
     argsAsString.push('args[' + i + ']'); 
    } 
    return eval('new cls(' + argsAsString.join(',') + ')'); 
} 

(bị đánh cắp từ another thread)

+0

Oh đó là ... một điểm tốt thực sự. Hmm, tự hỏi nếu điều này có bất kỳ vấn đề scoping? –

+0

Phạm vi không phải là một vấn đề, vì 'cls' và' args' lấy các chuỗi phạm vi của chúng với chúng khi chúng được truyền cho 'newApply'. – user123444555621

+0

Tôi tự hỏi tại sao (a) bạn chọn câu trả lời này và không chấp nhận câu trả lời từ câu hỏi khác và (b), bạn không bỏ phiếu để đóng bản sao này như một bản sao? –

2

Xin chúc mừng! Bạn vừa tìm thấy một trong những mụn cóc bí mật xấu nhất trong Javascript và những gì bạn muốn làm không thể được thực hiện.

Các cách giải quyết chung là một trong hai chức năng tạo wrapper (như bạn đã làm) hoặc cơ cấu lại các chức năng constructor để nhận danh sách/đối tượng thay vì rất nhiều lý lẽ.


Có một đề nghị cho một "..." cú pháp cho nhiều đối số trong Harmony (phiên bản kế tiếp của JS) nhưng cho đến khi sau đó không có cách nào để vượt qua một số biến của các đối cho một nhà xây dựng.

Việc chuyển danh sách hoặc đối tượng thường là một ý tưởng hay khi bạn có tấn đối số. Nó bảo vệ bạn khỏi bị xáo trộn trật tự một cách tình cờ và làm cho nó dễ dàng hơn để xử lý các tham số tùy chọn (như nó có vẻ là trong trường hợp của bạn).

new Foo("arg1", { 
    helpers: helpers, 
    options: optionsTemplate, 
    intruments: Assets.instruments 
}); 

Chỉnh sửa: Chỉ cần tìm thấy một câu hỏi khác về cùng một chủ đề này: Use of .apply() with 'new' operator. Is this possible?

Các vấn đề liên quan