2011-07-12 28 views
7

tôi là tạo ra đối tượng javascript bằng cách làm một cái gì đó như:hai cách để tạo ra đối tượng trong javascript

function field(name,label){ 
     this.name = name 
     this.label= label; 
} 

var a = new field("market","Mkt"). 

Sau đó, tôi gán một đối tượng khác.

object.newField = a; 

Cách thứ hai để làm việc đó là để tạo ra một tài sản mới trực tiếp

object.2ndNewField = { 
    name: "market2", 
    label:"Mkt2" 
} 

Tôi cố gắng đọc các đối tượng trong các chức năng khác. Họ hành xử khác nhau, tuy nhiên, khi tôi xâu chuỗi các đối tượng, có vẻ ok. Sự khác nhau giữa hai thuộc tính mà tôi tạo ra là gì?

btw có sự khác biệt nào của đối tượng sau không?

object.2ndNewField = { 
     "name": "market2", 
     "label":"Mkt2 
    } 
+0

Hai đối tượng hoạt động khác nhau như thế nào? – brainjam

Trả lời

6

Sự khác biệt là trong trường hợp đầu tiên, đối tượng tạo ra được thừa hưởng từ field.prototype sau đó Object.prototype (tức nội bộ [[Prototype]] của nó là field.prototype, mà nội bộ [[ Prototype]] là Object.prototype), trong trường hợp thứ hai, nó chỉ thừa kế từ Object.prototype.

Một cách khác để nhìn vào nó là:

object.newField instanceof field; // true 
object.newField instanceof Object; // true 

object.newField2 instanceof field; // false 
object.newField2 instanceof Object; // true 

hoặc các chuỗi thừa kế là:

object.newField -> field.prototype -> Object.prototype -> null 

object.newField2 -> Object.prototype -> null 

nơi '->' có nghĩa là "thừa hưởng từ".

+0

Tôi đang cố gắng duyệt qua đối tượng trong một hàm khác, field.prototype làm cho nó không hoạt động như tôi mong đợi. Có cách nào để sửa nó k? –

+0

@CKeven 'function F() {}; F.prototype = {hello: "world"}; var f = new F(); cảnh báo (f.hello); '<- Đó là tất cả để có nó. Đối tượng trong 'f' có một' [[prototype]] '* nhưng không * một thuộc tính' prototype' (một số trình duyệt hiển thị thuộc tính '__proto__' hoặc tương tự). Hàm Constructor, 'F' có thuộc tính' prototype' được sử dụng làm cơ sở cho các đối tượng mới '[[prototype]]'. –

+0

@CKeven Ít nhất FF hỗ trợ thuộc tính 'constructor' trên các đối tượng mới, nhưng tôi không biết spec này nói gì về điều này. Lưu ý rằng hàm Constructor 'prototype' được áp dụng cho đối tượng mới tại thời điểm' new' - gán một đối tượng mới cho 'prototype' sau này không có tác dụng đối với các đối tượng đã tạo trước đó (nhưng đối tượng nguyên mẫu có thể bị biến đổi, được chia sẻ, tất nhiên). –

1

Đối với tùy chọn Đầu tiên ... Tránh xa việc sử dụng "mới". Bạn có thể ảnh hưởng xấu đến không gian tên chung của bạn nếu "mới" được sử dụng sai, hoặc bỏ qua khi nó được sử dụng. Ngoài ra, bạn phải cẩn thận với việc sử dụng "điều này" ở một số nơi trong mã của bạn, vì nó có thể bị ràng buộc với một cái gì đó mà bạn không nghĩ là nó, hoặc thậm chí cả dữ liệu toàn cầu của bạn.

Trong tùy chọn thứ 2 bạn đã cung cấp, bạn có thể sử dụng an toàn cho các đối tượng chỉ được sử dụng làm bộ sưu tập dữ liệu/phương pháp (tức là hành vi "không giống lớp"). Nếu bạn muốn một cái gì đó mà bạn có thể tạo ra nhiều trường hợp với các biến/phương thức riêng và công khai và có thể được kế thừa từ, thì bạn nên sử dụng một hàm trả về một đối tượng.

Tôi đã viết khá lớn và ví dụ here cách tạo đối tượng cơ sở và sử dụng kế thừa một cách an toàn. Nếu bạn làm theo các liên kết, bạn sẽ thấy lý do tại sao tôi đã không gõ lại tất cả trên bài đăng này;).

Hy vọng điều này sẽ giúp ...

+0

Uhhh ..... "tránh xa ... mới" ... "ảnh hưởng xấu ... không gian tên"? Tôi không hiểu. 'new' không ảnh hưởng đến không gian tên. Cũng sử dụng 'mới'" sai "hoặc bỏ qua là không nghiêm trọng hơn một hành vi phạm tội hơn bất kỳ mã ngữ nghĩa không hợp lệ khác. –

+0

@pst, Nếu bạn định nghĩa một "lớp" giống như đối tượng trong JavaScript được dùng để "mới", và bạn quên sử dụng toán tử "mới" khi khởi tạo một đối tượng mới ... "this" bị ràng buộc với toàn cầu đối tượng, KHÔNG phải là đối tượng giống lớp. Điều này có thể gây ra nhiều vấn đề với các xung đột biến đổi với dữ liệu toàn cầu của bạn. Vì vậy, nếu bạn quên gọi mới khi tạo một đối tượng mới, bạn có thể thực hiện các khu vực khác của mã mà không biết, và bạn sẽ không bị lỗi. Nó thường là tốt hơn để sử dụng các đối tượng trở về từ chức năng ... đặc biệt là nếu bạn đang viết API – jyore

+0

1) Không có lớp học ;-) 2) Quên để xác định 'mới' là không khác với bất kỳ lỗi ngữ nghĩa khác - * nó là một lỗi trong mã phải được sửa và do đó không phải là duy nhất * (không có 'return' trong hàm nó được * dễ dàng phát hiện * khi cố gắng sử dụng đối tượng mới do kết quả của hàm sẽ là' undefined') 3) 'new' được yêu cầu sử dụng chuỗi' [[prototype]] 'vì [không may] thiếu khả năng xác định một bản mẫu sau khi tạo. –

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