2014-10-06 36 views
23

Tôi cố gắng để nhanh chóng HTMLDivElement mới trong nguyên cảoInstantiating phần tử html mới trong nguyên cảo

var elem = new HTMLDivElement(); 

nhưng trình duyệt ném

Uncaught TypeError: Illegal constructor. 

Cách giải quyết có vẻ là để sử dụng

var elem = document.createElement('div'); 

nhưng Tôi thấy điều này tối ưu cho các lý do khác nhau.

Tại sao tôi không thể tạo nhanh trực tiếp các phần tử DOM khi có một từ khóa mới cho trong trong lib.d.ts?

declare var HTMLDivElement: { 
    prototype: HTMLDivElement; 
    new(): HTMLDivElement; 
} 

Trả lời

33

Lưu ý rằng lỗi bạn nhận được ở đây là "Nhà xây dựng bất hợp pháp". Điều này khác với lỗi "đối tượng không phải là một chức năng" mà bạn sẽ nhận được nếu bạn đã viết new {}(), ví dụ.

Vì vậy, về mặt kỹ thuật, HTMLDivElementhiện có một hàm tạo. Nó chỉ là nhà xây dựng đặc biệt này ném một ngoại lệ thay vì tạo một đối tượng.

Thông thường lib.d.ts sẽ loại trừ các chữ ký vô dụng như vậy, nhưng TypeScript yêu cầu bên phải của toán tử instanceof có một hàm tạo. Nói cách khác, việc viết foo instanceof HTMLElement là hợp pháp, nhưng không phải là foo instanceof [] và sự khác biệt được xác định bởi thực tế là HTMLElement có một hàm tạo.

Có ba lựa chọn cơ bản trên bàn ở đây:

  1. Tháo chữ ký xây dựng từ các yếu tố DOM và loại bỏ các hạn chế về toán hạng phải instanceof 's. Điều này là không mong muốn vì bạn thực sự muốn nắm bắt lỗi khi ai đó vô tình viết mã như x instanceof foo thay vì x instanceof Foo (trong đó foo là một phiên bản Foo).
  2. Xóa chữ ký cấu trúc khỏi các phần tử DOM, nhưng giữ nguyên séc instanceof. Điều này là xấu bởi vì foo instanceof HTMLElement là một điều rất hợp lý để viết.
  3. Tình hình hiện tại, nơi các nhà thầu tồn tại nhưng bạn phải biết không gọi cho họ.

Bạn không thể xây dựng các phần tử DOM bằng cách sử dụng các nhà thầu bình thường vì bạn phải trải qua document.createElement. Đây là cơ bản cho các lý do kỹ thuật liên quan đến cách trình duyệt thực hiện các đối tượng này.

+1

tuyệt vời giải thích. Có thể có một nhận xét trong lib.d.ts giải thích điều này không? Hoặc bạn không muốn gây ô nhiễm lib.d.ts với các bình luận? –

+4

Bạn có nên thêm cảnh báo hoặc lỗi từ 'tsc' cho mã gọi các hàm tạo trên các lớp con của' Element' không? –

+0

Nếu bạn mở rộng HTMLElement, ví dụ 'class Thing mở rộng HTMLElement' thì bạn CÓ THỂ sử dụng mới để tạo một cá thể với' let t = new Thing() '. Sau đó, bạn có thể thêm nó vào DOM! – Kokodoko

3

Bạn đã nhầm cú pháp kiểu chữ với cú pháp C#.

Chỉ cần thay thế

var elem = new HTMLDivElement(); 

rộng

var elem = document.createElement('div'); 

hoặc

var elem = <HTMLDivElement>(document.createElement('div')); 

(nếu bạn cần phải sử dụng thuộc tính HTMLDivElement)

+2

Không có vấn đề với cú pháp, đó là một vấn đề ngữ nghĩa. – yoniLavi

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