2010-03-09 7 views
7

Đây là một thủ tục lisp mà chỉ cần thêm 'a' với giá trị tuyệt đối của 'b':Bắt tham chiếu đến đối tượng Function JavaScript đằng sau một nhà điều hành

(define (a-plus-abs-b a b) 
    ((if (> b 0) + -) a b)) 

Tôi nghĩ rằng đây là đẹp, và tôi đang cố gắng để tìm cách viết tốt nhất trong JavaScript. Nhưng mã JavaScript của tôi là không đẹp:

var plus = function(a,b) { 
    return a + b; 
}; 

var minus = function(a,b) { 
    return a - b; 
}; 

var aPlusAbsB = function(a,b) { 
    return (b > 0 ? plus : minus)(a,b); 
} 

Vấn đề chính là tôi không thể sử dụng +- những biểu tượng như tham chiếu đến các chức năng họ thực sự đại diện như tôi có thể với lisp. Có ai có thể đưa ra một cách duyên dáng hơn để làm một cái gì đó như thế này, hoặc có tôi nhấn một ranh giới ngôn ngữ?

Rõ ràng, tôi có thể làm điều này:

var aPlusAbsB = function(a,b) { 
    return a + Math.abs(b); 
} 

, nhưng đây là chi tiết của một thí nghiệm tưởng tượng hơn là một câu hỏi thực tế.

Có cách nào để tôi có thể tham khảo các chức năng chính trong ngôn ngữ JavaScript giống như chúng được người dùng xác định không?

+0

Bạn đã xem Functional.js và cú pháp kỳ quặc dễ thương của nó để biểu diễn các hàm đơn giản dưới dạng chuỗi? – Pointy

+0

Ngoài ra tôi không có ý tưởng cho dù có thực sự là trường hợp chức năng trong bất kỳ ý nghĩa thực sự cho các nhà khai thác số học tích hợp. – Pointy

+0

Tôi đã thấy thư viện Chức năng và trông rất thú vị. Tôi chỉ tự hỏi nếu có bất kỳ cách nào để làm điều này bằng cách sử dụng chỉ JS cốt lõi. Và @Pointy tôi đã tự hỏi điều tương tự. Chúng có thể không phải là các đối tượng Hàm, nhưng có logic ở đó thực hiện tương tự như cách một hàm thực thi. –

Trả lời

5

Đó là một ý tưởng rất hay - sẽ rất tuyệt vời để đánh giá các biểu thức toán học nhưng bạn không thể đặt toán tử (hoặc logic đằng sau nó) thành một biến. Xin lỗi :-)

+0

Tôi ghét cung cấp cho bạn một +1 vì lợi ích của OP, nhưng đó là sự thật, có rất ít bạn có thể làm về nó. –

+0

@musicfreak: lol cảm ơn ;-) Tôi thường nghĩ về điều này bởi vì đã có lần tôi phải kiểm tra trạng thái của một biến để quyết định có nên '+' hay '-', nhưng nó sẽ là quá nhiều mát hơn nếu tôi có thể chỉ cần thông qua '+' hoặc '-' thay vào đó - nó sẽ lưu toàn bộ câu lệnh' if'! –

+0

Trừ khi được chứng minh bằng cách khác bởi một số maven JavaScript lưu động, điều này có vẻ như câu trả lời :(. –

0

này là hơi đẹp hơn đề nghị của bạn, mặc dù nơi nào gần đẹp như đại diện lisp của bạn về khái niệm:

var aPlusAbsB = function(a, b) { 
    var plus = function(a, b) { 
     return a + b; 
    }; 
    var minus = function(a, b) { 
     return a - b; 
    }; 
    return (b > 0 ? plus : minus)(a, b); 
} 

này sẽ tương đương như sau trong chương trình:

(define a-plus-abs-b 
    (lambda (a b) 
    (let ((plus (lambda (a b) (+ a b))) (minus (lambda (a b) (- a b)))) 
     (cond ((> b 0) (plus a b)) 
     (else (minus a b)))))) 
3

Mặc dù không thanh lịch như mã LISP, bạn có thể tạo một hàm động hoạt động như một toán tử (trên số), nhưng không phải.

function op(o) { 
    return new Function("a", "b", "return a " + o + " b"); 
} 


function aPlusAbsB(a, b) { 
    return (b > 0 ? op('+') : op('-'))(a, b); 
} 

Bên cạnh đó, chúng ta có thể che giấu sự phức tạp của việc tạo ra các bên trong một nếu wrapper, nhưng đó là gần nhất tôi có thể nhận được :)

function is(expr, op1, op2) { 
    return expr ? op(op1) : op(op2); 
} 

function aPlusAbsB(a, b) { 
    return (is(b > 0, '+', '-')(a, b)); 
} 
1

Tôi nghĩ rằng tất cả mọi người khác đến đây đầu tiên, nhưng JS là chức năng hoàn toàn ít hơn so với lisp, các toán tử không phải là các hàm hoặc các đối tượng, mà là các toán tử.

5

Nó phụ thuộc vào khía cạnh nào của việc triển khai lisp mà bạn thấy đặc biệt đẹp. Tôi sẽ đề xuất một phiên bản khác của đề nghị của bạn mà tôi nghĩ rằng kết thúc lên một chút gần gũi hơn với cú pháp định nghĩa lisp của bạn bằng cách làm một số điều bẩn.

// Give ourselves + and - functions to level the playing field with lisp. 
Number.prototype['+'] = function(x)this+x; 
Number.prototype['-'] = function(x)this-x; 

// Now we can have some fun. 
var aPlusAbsB = function(a,b) a [b > 0 ? '+' : '-'] (b); 

// Some other notable language barrier differences, but not too dissimilar? 
// (define (a-plus-abs-b a b) ((if (> b 0) + -) a b)) 
0

Vâng, điều gần nhất bạn có thể làm là lồng hàm cộng và trừ bên trong.

var aPlusAbsB = function(a, b) { 
    return (function(a, b) { b > 0 ? a + b : a - b })(a, b); 
} 

Không hoàn toàn giống nhau, nhưng công việc được thực hiện một cách đầy đủ gián tiếp.