2010-09-24 44 views
5

Đây là những cách để tạo các đối tượng javascript:Hai cách tạo đối tượng javascript, tôi nên sử dụng đối tượng nào?

function apple(optional_params) { 
    this.type = "macintosh"; 
    this.color = "red"; 
    this.getInfo = function() { 
     return this.color + ' ' + this.type + ' apple'; 
    }; 
} 

var apple = { 
    type: "macintosh", 
    color: "red", 
    getInfo: function() { 
     return this.color + ' ' + this.type + ' apple'; 
    } 
} 

Tôi thực sự thích thứ hai một phần lớn vì nó Json cú pháp, nhưng tôi đã nhìn thấy nhiều người đầu tiên so với cái thứ hai.

  • Có sự khác biệt nào giữa chúng không?
  • Mỗi người có thể được gia hạn, kế thừa và nhân bản/sao chép không?
  • Trong trường hợp sau, tôi có thể dễ dàng tạo các phần tử lồng nhau, điều này có thể thực hiện với yếu tố đầu tiên không?
  • Trong trường hợp sau, tôi không thể chuyển các tham số tùy chọn?
  • Họ có đang phục vụ các mục đích khác nhau không? Nếu có, bạn có thể cung cấp cho các kịch bản mà tôi sẽ sử dụng một trong số họ.
+4

Không, nó không phải là JSON cú pháp, nó là một đối tượng chữ. JSON là một định dạng văn bản là một tập con của cú pháp ngữ pháp đối tượng Javascript. – Guffa

+1

json cũng không hỗ trợ chức năng –

Trả lời

2

Đây là cách tôi tạo các đối tượng Javascript trong hầu hết các trường hợp:

/** 
* This becomes the constructor of Apple, a type of fruit. 
*/ 
var Apple = function() { 
    // Object init here 
    // This becomes a "private" variable 
    var seeds = 50; 

    // This becomes "public" properties 
    this.color = 'red'; 
    this.weight = 100; // in grams if you wonder. 

    /** 
    * Do stuff to count the seeds 
    * This becomes a privileged method that can access private variables 
    * and be called from outside the object 
    */ 
    this.countSeeds = function() { 
     // Do stuff to count the seeds. 
     return seeds; 
    } 
} 

/** 
* Static functions can be utility functions that can be called separate from 
* object instances. They do not have access to any variables or functions 
* in the constructor. 
*/ 
Apple.getTypes = function() { 
    return ['golden', 'granny', 'red', 'pink']; 
} 

/** 
* Public function that gets the default color 
*/ 
Apple.prototype.getColor = function() { 
    return Apple.color; 
} 

/** 
* Public function that sets the color of the object instance. 
*/ 
Apple.prototype.setColor = function(color) { 
    this.color = color; 
    return this.color; 
} 

var golden = new Apple(); 
golden.setColor('yellow'); 
alert('The color of the apple is ' + golden.color); 
+0

Tôi nghĩ rằng bạn đã quên dấu ngoặc kép xung quanh" màu đỏ ". Và Apple.getColor() không hoạt động. Nó trả về "không xác định". Tại sao vậy? –

+0

Xin lỗi về điều đó. Các hàm tĩnh được gọi là các đối tượng bên ngoài và tự nhiên không có quyền truy cập vào các đối tượng nội bộ và các biến được thiết lập bởi hàm tạo. lỗi của tôi. Tôi đã viết ví dụ mà không kiểm tra. – thomasmalt

+0

Tên Apple của một lớp hoặc tên của một đối tượng? trông giống như lớp học là Apple và đối tượng là vàng – JavaDeveloper

0

Xin lỗi, tôi vẫn là một chút noob tại javascript, nhưng không phải là những chức năng này và không phải là đối tượng? Hướng đối tượng, có, nhưng chức năng? Khá quan tâm thực sự.

Ồ, tôi chỉ sử dụng cái đầu tiên. Tôi nghĩ rằng nó trông rõ ràng hơn với tôi bởi vì nó hoàn toàn tuyên bố "chức năng mới".

+0

Đặt làm nhận xét và tôi chắc chắn bạn sẽ nhận được câu trả lời :) –

+0

Trong JS, một hàm là một loại đối tượng –

+2

Thực ra hầu hết mọi thứ trở thành một đối tượng. [] = Đối tượng, {} = Đối tượng, hàm() {} = Đối tượng. Đó là một mô hình rất linh hoạt và mở ra một số sở hữu khá thú vị. – thomasmalt

3

Sự khác biệt là bạn có thể sử dụng lại thiết bị đầu tiên. Ví dụ:

function Apple(type, color) { 
    this.type = type; 
    this.color = color; 
    this.getInfo = function() { 
    return this.color + ' ' + this.type + ' apple'; 
    } 
} 

var red = new Apple("Macintosh", "red"); 
var green = new Apple("Granny Smith", "green"); 

vs

var red = { 
    type: "Macintosh", 
    color: "red", 
    getInfo: function() { 
    return this.color + ' ' + this.type + ' apple'; 
    } 
}; 

var green = { 
    type: "Granny Smith", 
    color: "green", 
    getInfo: function() { 
    return this.color + ' ' + this.type + ' apple'; 
    } 
}; 
+0

Không phải là có thể chuyển các tham số cho cái thứ hai bằng cách nào đó? –

+1

@ajsie: Bạn có thể bọc đối tượng theo nghĩa đen trong một hàm và chuyển các tham số cho hàm mà bạn sử dụng trong đối tượng. Đôi khi nó được sử dụng khi bạn muốn có một chức năng của nhà máy chứ không phải là một hàm tạo. – Guffa

3

Đối với đối tượng đầu tiên của bạn, bạn muốn đặt hàm thành viên trong nguyên mẫu, như ví dụ:

function apple(optional_params) { 
    this.type = "macintosh"; 
    this.color = "red"; 
} 

apple.prototype.getInfo = function() { 
    return this.color + ' ' + this.type + ' apple'; 
} 

Điều này làm cho "đối tượng "để chỉ tạo hai trường mới trong bộ nhớ (loại và màu) trong khi vẫn giữ chức năng như một phần của nguyên mẫu cho đối tượng đó. Đối tượng thứ hai của bạn (bảng băm) tạo ra một hàm mới cho từng đối tượng.

Vì vậy, như bạn có thể thấy bằng cách sử dụng phương pháp tiếp cận chức năng là tốt nếu bạn có rất nhiều chức năng, bởi vì các chức năng sau đó không mất thêm bộ nhớ.

Để làm rõ: Hai ví dụ của bạn tạo ra cùng một kết quả, nhưng nếu bạn đặt hàm trong mẫu thử nghiệm thì kết quả sẽ khác.

+0

Tôi không thể làm điều tương tự cho lần thứ hai, chỉ có các thuộc tính trong chuỗi json đó, sau đó chèn chúng sau đó với: "apple.getInfo = function() {...}"? –

+0

lưu ý bit 'prototype'. và có, có thể, miễn là bạn cũng tạo ra một nhà xây dựng cho nó. (đối tượng hàm chính nó là một hàm tạo theo mặc định khi sử dụng từ khoá 'new') –

2

Ví dụ thứ hai chỉ định nghĩa một thể hiện của Object, với một vài thuộc tính được đặt. Cái đầu tiên thú vị hơn nhiều.

Chức năng trong JavaScript có mục đích kép, một hàm làm chức năng/thủ tục bình thường và phương thức kia làm cơ sở cho kế thừa prototypal, tương tự như "lớp" trong OOP bình thường.

Ví dụ:

var apple = function() { 
    this.type = 'granny smith'; 
}; 
var myApple = new apple(); 
alert(myApple.type); // -> 'granny smith' 

Ở đây, chúng tôi đã xác định một "lớp" gọi apple, với một initializer mà đặt type tài sản. myApple sau đó được tạo dưới dạng phiên bản apple và thuộc tính type được thiết lập bởi trình khởi tạo apple().

(Là một sang một bên, new apple() cũng có thể được gọi là new apple với ngoặc bỏ qua và kết quả là vẫn như nhau, initializer vẫn gọi, nó chỉ nhận không có đối số)

Điều quan trọng khác sử dụng new cho chúng ta là sự thừa kế nguyên mẫu. Tất cả các chức năng đi kèm với một đối tượng nguyên mẫu mà chúng ta có thể thiết lập các thuộc tính. Các thuộc tính này sau đó trở thành các giá trị dự phòng cho các đối tượng mẫu không có giá trị riêng của chúng được xác định.

Ví dụ:

var greenApple = function() { }; 
var myApple = new apple(); 
alert(myApple.color); // -> undefined 
greenApple.prototype.color = 'green' 
alert(myApple.color); // -> green 

Ở đây, thiết greenApple.prototype.color ảnh hưởng đến tài sản màu cho myApple chúng tôi đã tạo ra. Đây là những gì được gọi là thừa kế prototypal, và nó có nhiều cách sử dụng.

 

Edit:Sau đây đề cập đến một phiên bản trước của câu hỏi đó đã được chỉnh sửa trong khi tôi đang viết những dòng này. Bạn có thể bỏ qua nó một cách an toàn trừ khi bạn đặc biệt quan tâm.

Bây giờ, trở lại ví dụ đầu tiên của bạn:

var apple = new function() { ... } 

Bởi vì bạn có từ khóa new trước khi định nghĩa hàm, hiệu quả là như tạo lớp táo, làm cho một đối tượng myApple, sau đó ném lớp táo xa. Nếu bạn có quyền truy cập vào lớp này, bạn có thể sử dụng .prototype để thêm thuộc tính nguyên mẫu, nhưng bạn không - tất cả được chứa trong biến số apple (trong điều khoản OOP) là một thể hiện của lớp, chứ không phải chính lớp đó.

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