2009-12-07 38 views
6

Hãy nhìn vào đoạn mã sau:cú pháp Strange các phương pháp số trong JavaScript

Number.prototype.isIn = function() { 
    for (var i = 0, j = arguments.length; i < j; ++i) { 
     if (parseInt(this, 10) === arguments[i]) { 
      return true; 
     } 
    } 
    return false; 
}; 

var x = 2; 
console.log(x.isIn(1,2,3,4,5)); // <= 'true' 
console.log(2.isIn(1,2,3,4,5)); // <= Error: 'missing) after argument list' 

Tại sao khi đó là một biến, mã hoạt động chính xác nhưng khi nó là một số chữ, nó không thành công?


Và cũng lạ, tại sao dòng sau hoạt động?

console.log((2).isIn(1,2,3,4,5)); // <= 'true' 

Trong dòng trên, tôi cơ bản đính kèm chữ trong dấu ngoặc đơn.

Trả lời

10

Đó là lỗi cú pháp vì bạn đại diện cho một số. Các chuỗi có thể hoạt động theo cách đó, chứ không phải số, bởi vì một khoảng thời gian ngay sau một số biểu thị một giá trị thập phân. Ký tự sau . gây ra lỗi.

-1

Sự hiểu biết của tôi cho rằng các con số là số nguyên, và không phải là một đối tượng. Tuy nhiên, khi bạn định nghĩa một biến là một số, thì nó sẽ trở thành một đối tượng Number() mới.

Vì vậy, hãy làm như sau;

var x = 10; 

Tương tự như vậy;

var x = new Number(10); 

Ví dụ thứ hai; Tôi chỉ có thể giả định rằng việc đặt các dấu ngoặc xung quanh số đã làm cho trình biên dịch JavaScript giả định rằng giá trị là một đối tượng Number() ẩn danh. Mà làm cho tinh thần tôi đoán ...

+3

'x = 10' và' x = số mới (10) 'không tương đương. –

+0

Đúng: 'alert (typeof 10);' so với 'alert (typeof new Number (10));' –

+0

Cảm ơn các bạn đã sửa. – Cammy

0

Mặc dù sự khác biệt thường là không rõ ràng vì chuyển đổi kiểu tự động, JavaScript hỗ trợ một số loại nguyên thủy cũng như các đối tượng:

var foo = 10; 
var bar = new Number(10); 
alert(foo.toString(16)); // foo is automatically wrapped in an object of type Number 
         // and that object's toString method is invoked 
alert(bar.toString(16)); // bar is already an object of type Number, 
         // so no type conversion is necessary before 
         // invoking its toString method 
var foo2 = "foo"; 
var bar2 = new String("foo"); 
alert(typeof foo2);  // "string" - note the lowercase "s", not a String object 
alert(typeof bar2);  // "object" 

alert(typeof true)  // "boolean" 
alert(typeof new Boolean(true)) // "object" 

và cái gì đó thực sự confuses vấn đề:

// the next line will alert "truthy" 
alert("Boolean object with value 'false'" + (new Boolean(false) ? " is truthy" : " is falsy")); 
// the next line will alert "falsy" 
alert("boolean primitive with value 'false'" + (false ? " is truthy" : " is falsy")); 

Mặc dù dựa trên chuyển đổi kiểu tự động làm cho cuộc sống một chút dễ dàng hơn, ta nên luôn luôn có ở mặt sau của tâm trí con người một sự hiểu biết tốt về những gì loại giá trị nguyên thủy của bạn và các đối tượng thực sự; một số lượng lớn các lỗi JS xuất hiện bởi vì mọi người không nhận ra rằng, ví dụ, một số trông giống như một số thực sự là một chuỗi hoặc một số hoạt động mà họ đã thực hiện đã dẫn đến một số được gán một giá trị mới là một chuỗi hoặc một đối tượng.

CHỈNH SỬA: để giải quyết chặt chẽ hơn câu hỏi ban đầu, hiện tại tôi đã không trả lời rõ ràng: 10.foo() sẽ gây ra lỗi cú pháp khi . được xem là dấu thập phân và foo() không phải là chuỗi hợp lệ các ký tự được phân tích cú pháp dưới dạng một số. (10).foo() sẽ hoạt động như dấu ngoặc đơn (10) tạo toàn bộ cấu trúc trước . thành một biểu thức duy nhất. Biểu thức này được đánh giá và trả về giá trị số nguyên thủy 10. Sau đó, . được xem là xử lý giá trị nguyên thủy trong ngữ cảnh đối tượng, do đó, nó được tự động gói trong một đối tượng thuộc loại Number (đây là chuyển đổi loại tự động đang hoạt động).Sau đó, thuộc tính foo của đối tượng đó, được tìm thấy trên chuỗi nguyên mẫu của nó, được tham chiếu; và số () cuối cùng khiến thuộc tính đó được coi là tham chiếu hàm và được gọi trong ngữ cảnh 'này' của đối tượng Số được bao quanh giá trị nguyên thủy tại điểm gặp phải ..

+0

'10' và' Số (10) 'giống hệt nhau. 'bar = Number (10)' không làm cho 'bar' là một đối tượng của kiểu số". Có lẽ bạn muốn so sánh '10' với' số mới (10) '? OR ''10'' so với' Số (' 10 ') '? –

+0

Rất tiếc, bắt tốt - thiếu 'mới'. Tôi nên sao chép công cụ này từ giao diện điều khiển nơi tôi làm bài kiểm tra của tôi thay vì gõ lại nó :-) – NickFitz

2

Josh đúng, nhưng bạn không phải sử dụng biến để sử dụng phương pháp số, mặc dù thường thuận tiện hơn để thực hiện việc này.

5.isIn(1,2,3,4,5) returns an error 

5.0.isIn(1.2.3.4.5) returns true, as does 
(5).isIn(1,2,3,4,5) 
+0

'5..isIn' và' 5 .isIn' cũng loại bỏ sự phân tích [phân tích cú pháp]. –

7

Hầu hết các câu trả lời đã cho biết dấu chấm sau một chữ số được coi là một phần của số này dưới dạng dấu tách phân số. Nhưng nếu bạn vẫn muốn sử dụng dấu chấm làm toán tử thì việc sửa chữa nhanh chóng và dễ dàng sẽ để lại khoảng trống giữa số và khoảng trắng.

2 .isIn(1,2,3,4,5) // <- notice the space between 2 and . 
+0

+1 hmm, đây là một cách sử dụng thú vị của khoảng trắng! –

+0

thực sự nó khá hợp lý - dấu chấm là một toán tử chuẩn trong JavaScript giống như + hoặc = hoặc -. Bạn có thể viết một cái gì đó như 4 + 5 để bạn có thể sử dụng 4. isIn(). – Andris

+0

@Andris, câu trả lời tuyệt vời. Tuy nhiên, chỉ cần lưu ý, thêm dấu ngoặc đơn là tốt hơn (2) .isIn (1,2,3,4,5,6) (theo nghĩa dễ đọc) – shabunc

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