2009-02-08 29 views
10

Xin chào, tôi đang thử kiểm tra xem đối số được chuyển vào hàm của tôi là tên lớp sao cho tôi có thể so sánh nó với các lớp khác bằng instanceof.Kiểm tra xem một cái gì đó có phải là một lớp trong javascript

Ví dụ:

function foo(class1, class2) { 
    // Test to see if the parameter is a class. 
    if(class1 is a class) 
    { 
    //do some kind of class comparison. 
    if(class2 is a class) 
    { 
     if(class1 instanceof class2) 
     { 
      //... 
     } 
    } 
    else 
    { 
     //... 
    } 
    } 
    else 
    //... 
} 

Đây có phải là có thể? Tôi gặp sự cố khi googleing câu trả lời.

+0

Bạn có đang sử dụng thư viện triển khai kế thừa cổ điển trong JavaScript không? – Nosredna

+0

Không, tôi chỉ sử dụng javascript cũ đơn giản: d – kgrad

Trả lời

15

Có thực sự có những điều như một "lớp" trong javascript - mọi thứ nhưng nguyên thủy là một đối tượng. Ngay cả các hàm cũng là các đối tượng.

instanceof KHÔNG hoạt động với chức năng. Kiểm tra này link.

function Car(make, model, year) 
{ 
    this.make = make; 
    this.model = model; 
    this.year = year; 
} 
var mycar = new Car("Honda", "Accord", 1998); 
var a = mycar instanceof Car; // returns true 
var b = mycar instanceof Object; // returns true 
+1

"mọi thứ đều là đối tượng" - Không chính xác. Các kiểu nguyên thủy (số, chuỗi, bool, null và undefined) không phải là các đối tượng. –

+1

@AndreasGrech - không chính xác, thậm chí các kiểu nguyên thủy có các thuộc tính và phương thức và chuỗi nguyên mẫu, v.v ... vì vậy chúng cũng là một loại đối tượng – Luckylooke

4

JavaScript không có lớp học. Nó có các chức năng, khi được sử dụng với new, có thể được sử dụng để tạo ra các cá thể đối tượng. Do đó, bạn thực sự muốn thử nghiệm nếu class2 là một hàm. Có nhiều cách để hoàn thành điều này; hiện tại (1.3) thực hiện isFunction() trong jQuery trông như thế này:

isFunction: function(obj) { 
    return toString.call(obj) === "[object Function]"; 
}, 

... Nhưng thấy ở đây cho một tóm tắt của các phương pháp khác nhau: Best method of testing for a function in JavaScript?

0

Bây giờ chúng ta có việc thực hiện nguồn gốc của ES6, có những "lớp học thật". Đây là phần lớn cú pháp đường cho sự thừa kế nguyên mẫu như với hàm xây dựng, nhưng có sự khác biệt tinh tế và hai không hoàn toàn có thể hoán đổi cho nhau.

Cho đến nay, cách duy nhất tôi đã tìm thấy là để có được những .toString() của hàm xây dựng nguyên mẫu của của đối tượng và kiểm tra nếu nó bắt đầu với class HOẶC nếu đối tượng có một constructor và .toString() của rằng bắt đầu với class. Lưu ý rằng nếu mã của bạn được biên dịch (tức là: hầu hết các thiết lập Babel hoặc TypeScript), thì điều này sẽ trả về function... thay vì class... khi chạy (vì các lớp được chuyển thành hàm dựng).

function isClass(obj) { 
    const isCtorClass = obj.constructor 
     && obj.constructor.toString().substring(0, 5) === 'class' 
    if(obj.prototype === undefined) { 
    return isCtorClass 
    } 
    const isPrototypeCtorClass = obj.prototype.constructor 
    && obj.prototype.constructor.toString 
    && obj.prototype.constructor.toString().substring(0, 5) === 'class' 
    return isCtorClass || isPrototypeCtorClass 
} 

này sẽ chỉ làm việc trong môi trường tự nhiên (Chrome, Firefox, Edge, Node.js, vv) đã thực hiện class cho mã mà chưa được transpiled để function.

Cách sử dụng:

class A {} 
class B extends A {} 
isClass(A) // true 
isClass(new A()) // true 
isClass(B) // true 
isClass(new B()) // true 

function C() {} 
isClass(C) // false 
isClass(new C()) // false 
isClass({}) // false 
isClass(Date) // false 
isClass(new Date()) // false 

//These cases return 'true' but I'm not sure it's desired 
isClass(Object.create(A)) // true  
const x = {} 
Object.setPrototypeOf(x, A) 
isClass(x) // true 

Nếu có một cách tốt hơn, tôi rất muốn biết nó là gì.

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