2010-09-24 6 views
12

Nó được sử dụng để làm gì nếu nó luôn trả về "đối tượng" như kiểu?Tại sao loại của javascript luôn trả về "đối tượng"?

--update

luôn cho Elements hoặc danh sách.

+11

Nó rất hữu ích bởi vì nó không làm điều đó. –

+0

Một số khách hàng trả về typeof = 'function' cho nodeLists trả về từ các phương thức như 'getElementsByTagName'. Tôi đề cập đến nó bởi vì nó gần đây bit tôi khi làm việc với Safari trên cửa sổ. – kennebec

+0

'console.log (typeof" foo "); // string' & 'console.log (typeof String (" foo ")); // string' 'console.log (typeof new String (" foo ")); // object' Chú ý đến việc sử dụng 'new' – Jowen

Trả lời

20

Loại JS không phải lúc nào cũng trả về 'đối tượng', nhưng nó trả về đối tượng cho những thứ mà mọi người có thể không coi là đối tượng - tức là mảng, và cũng là kỳ quặc, cho null.

Đối với mảng này là chính xác, vì theo như JS có liên quan, mảng là đối tượng; chúng giống nhau. Mảng chỉ là một lớp khác, và bạn có thể khởi tạo các đối tượng kiểu Array, nhưng chúng vẫn được coi là đối tượng.

This page có danh sách các loại trong JS, cùng với câu trả lời bạn sẽ nhận được cho mỗi loại từ typeof. Nó cũng có một số mã JS để ghi đè hàm typeof với một hàm trả về các thông tin hữu ích hơn. Nếu bạn đang lo lắng về nó không hữu ích, bạn có thể thực hiện một cái gì đó như thế nếu bạn muốn.

+0

Google Chrome hiện trả về 'hàm' cho tôi, khi tôi cung cấp 'typeof Array' (hoặc bất kỳ loại mảng nào khác, chẳng hạn như Int8Array, hoặc Float32Array) ... –

+0

Liên kết đã chết:/ –

5

Nó luôn không trả lại "đối tượng":

alert(typeof "hello"); 

Điều đó nói rằng, một thủ thuật (có thể) có ích hơn để kiểm tra đối tượng là sử dụng Object.prototype.toString.call() và nhìn vào kết quả:

var t = Object.prototype.toString.call(itIsAMystery); 

Điều đó sẽ cho bạn một chuỗi như [object Foo] với "Foo" là hàm tạo (tôi nghĩ) phần thú vị. Đối với các kiểu "gốc" (như Date hoặc String), bạn lấy lại tên của hàm khởi tạo đó.

+1

* ... với" Foo "là ... * giá trị của thuộc tính bên trong' [[Class]], đại diện cho * * cho các đối tượng gốc * - một đặc điểm kỹ thuật được xác định * phân loại * -không thực sự là một * loại *! - và đối với các đối tượng lưu trữ, về cơ bản nó có thể là bất cứ điều gì .... – CMS

+0

Wow nhờ @CMS! – Pointy

+0

Lưu ý rằng toán tử 'typeof' _does_ luôn trả về' "đối tượng" 'cho phạm vi' this' của hàm _ (trừ khi phạm vi xảy ra là hàm) _. Xem ["Tại sao loại này trở lại" đối tượng "?"] (Http://stackoverflow.com/questions/4390658/why-does-typeof-this-return-object) – Phrogz

-1

Bạn phải hiểu rằng hệ thống kiểu trong JavaScript là động với một vài loại "nguyên thủy" để xây dựng dựa trên. Bằng cách xử lý tất cả các đối tượng phức tạp như kiểu "đối tượng", điều này cho phép bạn gõ và gọi các phương thức mà không nhất thiết phải biết loại đối tượng đang được truyền xung quanh giả sử kiểu đó có lời gọi hàm được thực thi. Trong một ngôn ngữ lập trình động tất cả mọi thứ là một "đối tượng".

+0

Ngôn ngữ gõ không phải lúc nào cũng bỏ qua các loại - ví dụ, Python được gõ và có một loại hữu ích() cho bạn biết loại đối tượng. – mikemaccana

+0

Bạn có thể chuyển bất kỳ loại nào bạn thích vào bất kỳ đâu, nhưng điều đó không có nghĩa là có các loại _no_ khác với đối tượng. – byxor

2

Theo kinh nghiệm của tôi, vấn đề chính với typeof xuất phát từ phân biệt giữa các mảng, các đối tượng và các giá trị rỗng (tất cả các đối tượng "trả về").

Để làm điều này, đầu tiên tôi kiểm tra typeof sau đó tôi kiểm tra các trường hợp null hoặc các "đối tượng" nhà xây dựng, như thế này:

for (o in obj) { 
    if (obj.hasOwnProperty(o)) { 
     switch (typeof obj[o]) { 
      case "object": 
       if (obj[o] === null) { 
        //do somethign with null 
       } else { 
        if (obj[o].constructor.name === "Array") { 
         //do something with an Array 
        } else { 
         //do something with an Object 
        } 
       } 
       break; 
      case "function": 
       //do something with a function 
       break; 
      default: 
       //do something with strings, booleans, numbers 
       break; 
     } 
    } 
} 
1

Một cần phải được một chút cẩn thận với toán tử typeof. Nó trả về "đối tượng" cho một null, "số" cho NaN, "số" cho Infinity, "đối tượng" cho một "số mới (1)" và "đối tượng" cho một mảng.

Khi kiểm tra sự tồn tại của biến (typeof variable! == "undefined") đôi khi cần kiểm tra đầu tiên (biến == null) vì typeof trả về "đối tượng" cho biến được gán cho null.

Đây là một chút rõ ràng nhưng người ta cũng phải cẩn thận không gọi một hàm khi kiểm tra typeof vì kiểu trả về của hàm sẽ được báo cáo chứ không phải là "hàm".

+0

Điều này rất hữu ích cho tình huống của tôi khi tôi có số, chuỗi, số không và đối tượng mà tôi đã lặp lại. Tôi đã có thể cô lập các đối tượng từ các null để biến đổi chúng. –

1

Để thêm vào với những người khác, typeof trả về cả đối tượng và nguyên thủy. Có 5 kiểu nguyên thủy trong javascript: undefined, null, boolean, string và number. Tất cả những thứ khác là một đối tượng. Khi typeof được áp dụng cho bất kỳ loại đối tượng nào khác ngoài Function, nó chỉ trả về “object”.Khi được áp dụng cho một hàm, nó trả về một đối tượng hàm.

Vì vậy, ví dụ:

  • typeof true; // trả về kiểu nguyên thủy "boolean"
  • typeof 123; // trả về kiểu nguyên thủy "number"
  • typeof null // trả về "đối tượng" là một sai lầm, nhưng cho đến nay không có sửa chữa trong phiên bản ECMAScript khác, chỉ cần nói về làm như vậy.
  • typeof đối tượng // trả về "đối tượng", có ý nghĩa

Để expound thêm về câu trả lời của chóp, có trong tất cả các đối tượng Javascript một tài sản nội bộ được gọi là [[Lớp]] trong ECMAScript 5. Để để hiển thị giá trị thực của đối tượng, bạn có thể tham chiếu thuộc tính [[Class]] bằng cách sử dụng: Object.prototype.toString. Để tránh một số đối tượng được xây dựng trong chuyên ngành ghi đè lênString bạn sử dụng phương thức nội bộ của cuộc gọi sẽ tiết lộ loại đối tượng thực tế.

Vì vậy, thay vì nhận được đối tượng chung chung lại từ toString:

var dateObject = Object.prototype.toString(new Date); 
document.write(dateObject);//[object Object] 

Bạn có thể nhận các loại đối tượng thực tế sử dụng Call:

var dateObject = Object.prototype.toString.call(new Date); 
document.write(dateObject);//[object Date]