2011-01-28 41 views
8

Cách tốt nhất để tìm hiểu xem biến có phải là một chuỗi hay không (và, tương tự như vậy, một số, một boolean, vv)?Kiểm tra loại biến

Thông thường, bạn sẽ tìm thấy:

function isString(value) { 
    return typeof value === 'string'; 
} 

Nhưng mọi người quên rằng người ta cũng có thể tạo ra chuỗi các đối tượng trực tiếp sử dụng var foo = new String("bar"); - cho dù đó là một ý tưởng tốt hay không là một vấn đề hoàn toàn khác nhau.

Vì vậy, con đường để đi đến đây là gì? Tôi có thể nghĩ đến - và đã thấy - cách tiếp cận khác nhau (hơi đơn giản):

// option 1 
function isString(value) { 
    return (typeof value === 'string') || 
      /^function String\(\)/.test(value.constructor + ''); 
} 

hoặc

// option 2 
function isString(value) { 
    return (typeof value === 'string') || 
      (value.constructor === String); 
} 

hoặc

// option 3 
function isString(value) { 
    return (typeof value === 'string') || 
      value instanceof String; 
} 

Có một "tốt nhất" con đường để đi về vấn đề này ? Hay tất cả chúng đều tương đương nhau?

Trả lời

5

Trong số ba tùy chọn hiện tại, người đầu tiên cảm thấy khá khó chịu với tôi vì nó sử dụng cụm từ thông dụng để kiểm tra biểu diễn chuỗi là value.constructor. Nó hoạt động, nhưng nó vẫn cảm thấy hacky (có lẽ nó chỉ là tôi).

Lựa chọn thứ hai sẽ chỉ làm việc cho literals chuỗi, chuỗi được tạo ra từ concatenating đối tượng và các đối tượng được thực hiện với các nhà xây dựng new String() hiện có, trong khi lựa chọn thứ ba nên làm việc với các đối tượng thực hiện với sự new String() constructor hoặc bất kỳ đối tượng khác được thừa kế từ String()(Tôi không chắc chắn về việc thừa kế JavaScript; ai đó có thể xác nhận điều này?).

Thuộc tính constructor cũng tồn tại đối với nguyên thủy/chữ, không chỉ các đối tượng bao bọc được tạo bằng cách sử dụng new. Điều này làm cho việc kiểm tra typeof trong các tùy chọn khá dư thừa thứ hai:

function isString(value) { 
    return value.constructor === String; 
} 

alert(isString("test1"));    // true 
alert(isString(new String("test2"))); // true 

Tuy nhiên, không giống như các tùy chọn thứ ba nó có thể không làm việc với các đối tượng với nhà thầu khác hơn String() mà kế thừa từ String().

câu trả lời của tôi sử dụng chuỗi như một ví dụ để phản ánh các câu hỏi nhưng ý tưởng tương tự áp dụng cho Number, Boolean, Function, Object, Array và các loại khác.

+0

Gọn gàng, tôi không biết điều đó (ít nhất là tôi chưa bao giờ nghĩ về nó;) Tuy nhiên, không thực sự trả lời câu hỏi. – n3rd

+0

@ n3rd: Làm cách nào để nó không trả lời câu hỏi khác ngoài câu hỏi không phải là một trong ba tùy chọn hiện tại? – BoltClock

+0

+1. Vừa mới đăng bài này. Liệu điều này bắt (gasp) subclasses của String mặc dù? – Skurmedel