--- title: Working with objects slug: Web/JavaScript/Guide/Working_with_Objects translation_of: Web/JavaScript/Guide/Working_with_Objects ---
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}

JavaScript được thiết kế trên mô hình đối tượng đơn giản. Một object là một tập hợp các thuộc tính, và một thuộc tính là sự liên kết giữa một cái tên và giá trị. Giá trị của một thuộc tính có thể là một hàm. Ngoài những đối tượng được định nghĩa trước trong trình duyệt, bạn có thể định nghĩa những đối tượng của riêng bạn. Chương này mô tả cách sử dụng những đối tượng, những thuộc tính, những hàm, và phương thức, cũng như cách thức để tạo đối tượng riêng của mình.

Tổng quan về Objects

Objects trong JavaScript, cũng tương tự như những ngôn ngữ khác, có thể so sánh như đối tượng trong đời thường. Khái niệm của objects trong JavaScript có thể được hiểu như những đối tượng thực tế trong đời thực.

Trong JavaScript, một object là một thực thể độc lập, với thuộc tính và kiểu. Lấy cái tách làm ví dụ. Cái tách là một object có những thuộc tính của riêng nó. Một cái tách có màu sắc, thiết kế, trọng lượng, chất liệu tạo ra nó, vân vân... Tương tự như vậy, JavaScript objects có thể có những thuộc tính định nghĩa nên đặc tính của nó.

Objects and thuộc tính

Một JavaScript object có những thuộc tính liên kết với nó. Một thuộc tính của một object có thể được giải thích như là một biến mà được gắn vào object đó. Những thuộc tính của object cơ bản cũng là những biến JavaScript bình thường, chỉ đặc biệt là được gắn lên object. Thuộc tính của object định nghĩa đặc tính của object. Chúng ta truy xuất thuộc tính của object với ký hiệu ".":

objectName.propertyName

Giống như những biến JavaScript, cả tên của object (có thể được xem như là 1 biến thông thường) và tên thuộc tính thì cũng phân biệt hoa thường. Bạn có thể định nghĩa một thuộc tính bằng cách gán giá trị cho nó. Ví dụ hãy tạo đối tượng myCar và gắn thuộc tính cho nó như make, model, and year như sau:

var myCar = new Object();
myCar.make = 'Ford';
myCar.model = 'Mustang';
myCar.year = 1969;

Những thuộc tính không được gán giá trị sẽ có giá trị {{jsxref("undefined")}} (lưu ý nó là không {{jsxref("null")}}).

myCar.color; // undefined

Thuộc tính của JavaScript object có thể được truy xuất hoặc thiết lập bằng cách dùng dấu ngoặc vuông (xem property accessors để tham khảo chi tiết). Objects thỉnh thoảng cũng được gọi là mảng liên kết, vì mỗi thuộc tính được liên kết với một giá trị kiểu chuỗi mà có thể được dùng để truy xuất thuộc tính đó. Ví dụ bạn có thể truy xuất những thuộc tính của myCar object như sau:

myCar['make'] = 'Ford';
myCar['model'] = 'Mustang';
myCar['year'] = 1969;

Tên thuộc tính của một object có thế là chuỗi ký tự hợp lệ bất kỳ, hoặc bất kỳ thứ gì có thể chuyển đổi được thành chuỗi, bao gồm cả chuỗi rỗng. Tuy nhiên, bất kỳ tên thuộc tính nào mà không phải là 1 định danh hợp lệ trong JavaScript (ví dụ, một thuộc tính mà tên có khoảng trắng hoặc gạch ngang, hoặc bắt đầu bằng số) chỉ có thể truy xuất bằng cách dùng dấu ngoặc vuông []. Ký pháp này cũng rất hữu dụng khi tên thuộc tính được xác định động (khi tên thuộc tính chỉ được xác định lúc thực thi). Như trong ví dụ sau:

// Khởi tạo 4 biến và gán giá trị cho chúng trên cùng một dòng lệnh
// phân cách bởi dấu ","
var myObj = new Object(),
    str = 'myString',
    rand = Math.random(),
    obj = new Object();

myObj.type              = 'Dot syntax';
myObj['date created']   = 'String with space';
myObj[str]              = 'String value';
myObj[rand]             = 'Random Number';
myObj[obj]              = 'Object';
myObj['']               = 'Even an empty string';

console.log(myObj);

Chú ý tất cả biểu thức được làm khóa trong dấu ngoặc vuông đều được chuyển đổi thành kiểu chuỗi, bởi vì objects trong JavaScript chỉ chấp nhận khóa là kiểu chuỗi. Ví dụ trong đoạn mã trên khi khóa obj được thêm vào myObj, JavaScript sẻ gọi phương thức obj.toString(), và lấy kết quả đó làm khóa.

Bạn cũng có thể truy xuất thuộc tính bằng cách dùng giá trị chuỗi mà nó được lưu trong một biến:

var propertyName = 'make';
myCar[propertyName] = 'Ford';

propertyName = 'model';
myCar[propertyName] = 'Mustang';

Bạn có thể sử dụng dấu ngoặc vuông với for...in để duyệt qua tất cả thuộc tính có thể đếm của object. Để minh họa cách nó hoạt động, hãy xem xét hàm sau đây, nó sẽ hiển thị những thuộc tính của đối tượng dựa vào 2 đối số gồm đối tượng (obj) và tên (objName) của đối tượng truyền vào cho hàm:

function showProps(obj, objName) {
  var result = '';
  for (var i in obj) {
    // obj.hasOwnProperty() is used to filter out properties from the object's prototype chain
    if (obj.hasOwnProperty(i)) {
      result += objName + '.' + i + ' = ' + obj[i] + '\n';
    }
  }
  return result;
}

Như vậy, khi ta gọi showProps(myCar, "myCar") thì kết quả được trả về như sau:

myCar.make = Ford
myCar.model = Mustang
myCar.year = 1969

Liệt kê những thuộc tính của một object

Bắt đầu từ ECMAScript 5, có 3 cách để liệt kê/duyệt danh sách thuộc tính của object:

Trước ECMAScript 5, không có cách thức có sẵn để liệt kê tất cả thuộc tính của một object. Tuy nhiên, chúng ta có thực hiện việc  đó bằng hàm sau:

function listAllProperties(o) {
	var objectToInspect;
	var result = [];

	for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)) {
      result = result.concat(Object.getOwnPropertyNames(objectToInspect));
	}

	return result;
}

Cách này rất hữu ích khi chúng ta muốn hiển thị những thuộc tính ẩn (những thuộc tính trong chuỗi prototype mà không thể truy xuất thông qua object, bởi vì một thuộc tính khác có cùng tên ở lớp trước của chuỗi prototype đã đè lên nó). Việc liệt kê những thuộc tính có thể truy xuất chỉ có thể dễ dàng hoàn thành bằng cách xóa bỏ trùng lặp trong mảng.

Tạo những object mới

JavaScript có một số object được định nghĩa sẵn. Ngoài ra, bạn có thể tạo định nghĩa những object mới. Bạn có thể tạo một object sử dụng bộ khởi tạo object (object initializer). Cách khác, bạn có thể tạo hàm dựng và rồi khởi tạo đối tượng bằng cách gọi hàm đó với toán tử new đặt trước.

Sử dụng bộ khởi tạo object

Ngoài việc khởi tạo object bằng cách dùng hàm dựng, bạn có thể tạo object bằng cách sử dụng bộ khởi tạo (object initializer). Sử dụng bộ khởi tạo thỉnh thoảng cũng được hiểu là cách khởi tạo bằng cách dùng literal. "Bộ khởi tạo" ("Object initializer") thì đồng nhất với thuật ngữ được sử dụng trong C++.

Cú pháp cho việc tạo một object bằng bộ khởi tạo la:

var obj = { property_1:   value_1,   // property_# may be an identifier...
            2:            value_2,   // or a number...
            // ...,
            'property n': value_n }; // or a string

Trong đó obj là tên của object mới, mỗi property_i là một định danh (hoặc là một tên, một số, hoặc một chuỗi dạng literal), và mỗi value_i là một biểu thức mà giá trị được gán cho property_i . obj và phép gán là không bắt buộc; nếu bạn không cần tham chiếu đến object đó ở chổ khác, bạn không cần assign nó cho một biến. (lưu ý bạn có thể cần bao object literal lại bằng dấu ngoặc nếu nó xuất hiện ở chổ cần như là một câu lệnh, làm như vậy để tránh gây nhầm lẩn với câu lệnh khối.)

Bộ khởi tạo object là những biểu thức, và mỗi bộ khởi tạo object sẽ tạo ra object mỗi khi biểu thức đó được tính toán. Bộ khởi tạo object tạo ra những đối tượng riêng biệt và chúng không bằng nhau khi so sánh bằng ==. Những đối tượng được tạo ra bằng cách new Object() cũng như những đối tượng được tạo ra bằng object literal đều là thực thể (instance) của Object.

Câu lệnh sau tạo một đối tượng và gán nó cho biến x khi và chỉ khi biểu thức cond là true:

if (cond) var x = {greeting: 'hi there'};

Đoạn mã sau tạo đối tượng myHonda với ba thuộc tính. Lưu ý thuộc tính engine cũng là một object và nó có những thuộc tính riêng của nó.

var myHonda = {color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}};

Bạn cũng có thể dùng bộ khởi tạo object để tạo mảng. Tham khảo array literals.

Sử dụng hàm dựng

Ngoài ra, bạn có thể tạo một object với hai bước sau đây:

  1. Định nghĩa kiểu cho object bằng cách khai báo một hàm dựng. Bạn nên đặt tên hàm với chữ hoa cho ký tự đầu tiên.
  2. Tạo một thực thể của đối tượng với toán tử new.

Để định nghĩa một kiểu dữ liệu object, tạo một hàm cho kiểu dữ liệu đó rồi chỉ định tên, những thuộc tính và phương thưc. Ví dụ, giả sử bạn muốn tạo một kiểu dữ liệu cho cars. Bạn đặt tên cho kiểu dữ liệu đó là Car, và bạn muốn nó có những thuộc tính như make, model, và year. Để làm được điểu này, bạn sẽ viết hàm sau:

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}

Lưu ý cách sử dụng this để gán trị giá trị cho những thuộc tính của object dựa vào giá trị được truyền vào cho hàm.

Bây giờ bạn có thể tạo một object tên mycar như sau:

var mycar = new Car('Eagle', 'Talon TSi', 1993);

Câu lệnh này tạo mycar gán những giá trị cụ thể cho những thuộc tính của nó. Giá trị của mycar.make là chuỗi "Eagle", mycar.year là số 1993, và tiếp tuc như thế.

Bạn có thể tạo bao nhiêu Car object đều được bằng toán tử new. Như ví dụ sau:

var kenscar = new Car('Nissan', '300ZX', 1992);
var vpgscar = new Car('Mazda', 'Miata', 1990);

Một object có thể có một thuộc tính mà giá trị là một object khác. Ví dụ như, giả sử bạn định nghĩa một object tên person như sau:

function Person(name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}

và sau đó khởi tạo hai object person mới như sau:

var rand = new Person('Rand McKinnon', 33, 'M');
var ken = new Person('Ken Jones', 39, 'M');

Và rồi, bạn có thể viết lại định nghĩa của Car để thêm thuộc tính owner mà nhận giá trị là một đối tượng kiểu person, như sau:

function Car(make, model, year, owner) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.owner = owner;
}

Để khởi tạo object mới, bạn viết những câu lệnh sau:

var car1 = new Car('Eagle', 'Talon TSi', 1993, rand);
var car2 = new Car('Nissan', '300ZX', 1992, ken);

Lưu ý rằng thay vì truyền vào một hằng chuỗi hoặc giá trị số khi tạo những object mới, câu lệnh trên truyền vào những đối tượng randken như là đối số cho owner. Sau đó nếu bạn muốn tìm tên của owner của car2, bạn có thể truy xuất như sau:

car2.owner.name

Lưu ý rằng bạn có thể luôn luôn thêm một thuộc tính mới vào những object đã được tạo ra. Như ví dụ câu lệnh sau:

car1.color = 'black';

thêm vào thuộc tính color cho car1, và gán giá trị cho nó là "black". Tuy nhiên, việc này không ảnh hưởng lên những object khác. Để thêm thuộc tính cho tất cả object của cùng một kiểu, bạn phải thêm thuộc tính đó khi định nghĩa kiểu đối tượng Car.
 

Sử dụng Object.create

Những object có thể được tạo ra bằng phương thức {{jsxref("Object.create()")}}. Phương thức này có thể rất hữu ích, bởi vì nó cho phép bạn chọn prototype cho object bạn muốn tạo ra, mà không cần phải định nghĩa hàm dựng.

// Animal properties and method encapsulation
var Animal = {
  type: 'Invertebrates', // Default value of properties
  displayType: function() {  // Method which will display type of Animal
    console.log(this.type);
  }
};

// Create new animal type called animal1
var animal1 = Object.create(Animal);
animal1.displayType(); // Output:Invertebrates

// Create new animal type called Fishes
var fish = Object.create(Animal);
fish.type = 'Fishes';
fish.displayType(); // Output:Fishes

Sự Kế  Thừa

Tất cả object trong JavaScript kế thừa từ ít nhất một object khác. Object mà được kế thừa từ nó thì được xem như là prototype, và những thuộc tính được kế thừa có thể được tìm thấy trong đối tượng prototype của hàm dựng. Xem thêm Inheritance and the prototype chain

Đánh chỉ mục thuộc tính object

Bạn có thể tham chiếu tới một object hoặc là bằng tên thuộc tính hoặc là bằng chỉ mục. Nếu bạn định nghĩa thuộc tính bằng tên, thì sau đó bạn phải dùng tên để truy xuất thuộc tính đó, còn nếu bạn định nghĩa thuộc tính bằng chỉ mục (một số), bạn phải dùng chỉ mục để truy xuất.

Giới hạn này áp dụng khi bạn tạo một object và thuộc tính của nó với hàm dựng (như chúng  ta đã làm với kiểu Car) và khi bạn định nghĩa những thuộc tính riêng lẻ một cách tường minh (ví dụ như , myCar.color = "red"). Nếu bạn định nghĩa thuộc tính với một chỉ mục, chẳng hạn như myCar[5] = "25 mpg", thì bạn phải tham chiếu đến thuộc tính đó với chỉ mục myCar[5].

Ngoại trừ nếu đó là object giống mảng (array-like), ví dụ như những object tạo ra từ HTML như forms object. Bạn có thể tham chiếu đến những object đó bằng cách hoặc là dùng số (dựa vào thứ tự nó xuất hiện trong document) hoặc là tên (nếu được định nghĩa). Ví dụ, nếu thẻ <FORM> thứ hai trong document có thuộc tính NAME là "myForm", bạn có thể tham chiếu đến form bằng cách document.forms[1] hoặc document.forms["myForm"] hoặc document.forms.myForm.

Định nghĩa những thuộc tính cho kiểu dữ liệu object

Bạn có thể thêm một thuộc tính cho một object đã định nghĩa trước đó bằng cách sử dụng thuộc tính prototype. Điều này định nghĩa một thuộc tính mà sẽ được chia sẻ bởi tất các các thuộc tính của cùng kiểu dữ liệu đó, không riêng cho một thực thể nào của kiểu đó. Đoạn mã sau sẽ thêm thuộc tính color cho tất cả các object của kiểu Car, và rồi gán giá trị cho thuộc tính color của object car1.

Car.prototype.color = null;
car1.color = 'black';

Xem thêm prototype property của object Function trong JavaScript reference.

Định nghĩa phương thức

Một phương thức là một hàm liên kết với một object, hoặc, có thể nói phương thức là một thuộc tính của object có giá trị là một hàm. Phương thức được định nghĩa giống như cách định nghĩa hàm, ngoài trừ việc chúng phải được gán như là thuộc tính của một object. Xem thêm method definitions. Ví dụ:

objectName.methodname = functionName;

var myObj = {
  myMethod: function(params) {
    // ...do something
  }

  // OR THIS WORKS TOO

  myOtherMethod(params) {
    // ...do something else
  }
};

objectName là một object đã được tạo trước đó, methodname là tên mà bạn đang gán cho phương thức, và functionName là tên của hàm.

Sau đó bạn có thể gọi hàm trong ngữ cảnh của object như sau:

object.methodname(params);

Bạn có thể định nghĩa phương thức của một kiểu object bằng cách thêm định nghĩa phương thức vào trong hàm dựng. Bạn có thể định nghĩa một hàm mà sẽ định dạng và hiển thị những thuộc tính của những đối tượng kiểu Car đã được định nghĩa trước, ví dụ:

function displayCar() {
  var result = 'A Beautiful ' + this.year + ' ' + this.make
    + ' ' + this.model;
  pretty_print(result);
}

trong đó pretty_print được giả định là một hàm đã được định nghĩa trước để hiển thị đường kẻ ngang và chuỗi kết quả. Lưu ý tham chiếu this đang trỏ đến đối tượng mà phương thức đang gắn trên đó.

Bạn có thể tạo hàm này thành phương thức của lớp Car bằng câu lệnh sau:

this.displayCar = displayCar;

khi định nghĩa kiểu object Car. Cài đặt đầy đủ của Car bây giờ sẽ là:

function Car(make, model, year, owner) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.owner = owner;
  this.displayCar = displayCar;
}

Rồi sau đó bạn có thể gọi phương thức displayCar trên mỗi đối tượng như sau:

car1.displayCar();
car2.displayCar();

Sử dụng this để tham chiếu đối tượng

JavaScript có từ khóa đặc biệt, this, mà bạn có thể sử dụng bên trong phương thức để tham chiếu đến object hiện tại. Ví dụ, giả sử bạn có một hàm tên là validate để kiểm tra giá trị của thuộc tính của một object là giá trị cao hay thấp:

function validate(obj, lowval, hival) {
  if ((obj.value < lowval) || (obj.value > hival)) {
    alert('Invalid Value!');
  }
}

Sau đó, bên trong hàm handler của event onchange của mỗi phần tử của form bạn có thể gọi hàm validate như ví dụ sau:

<input type="text" name="age" size="3"
  onChange="validate(this, 18, 99)">

Nói chúng, this trỏ đến object đang gọi bên trong hàm.

Khi kết hợp với thuộc tính form, this có thể tham chiếu đến form cha của object hiện tại. Trong ví dụ sau, form myForm chứa đối tượng Text và một nút. Khi user nhấp lên cái nút, giá trị của đối tượng Text được gán bằng tên của form. Hàm thực thi của sự kiện onclick của cái nút sử dụng this.form để tham chiếu đến form cha, myForm.

<form name="myForm">
<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
<p><input name="button1" type="button" value="Show Form Name"
     onclick="this.form.text1.value = this.form.name">
</p>
</form>

Định nghĩa getters và setters

Một getter là một phương thức mà nhận giá trị của một thuộc tính cụ thể. Một setter là một phương thức thiết lập giá trị cho một thuộc tính cụ thể. Bạn có thể định nghĩa getters và setters cho bất kỳ object nào có thể là do runtime tạo sẵn hoặc do người dùng định nghĩa. Chúng ta dùng cú pháp của object literal để tạo getter và setter.

Đoạn mã sau minh họa cách định nghĩa và thao tác trên getter và setter.

var o = {
  a: 7,
  get b() {
    return this.a + 1;
  },
  set c(x) {
    this.a = x / 2;
  }
};

console.log(o.a); // 7
console.log(o.b); // 8
o.c = 50;
console.log(o.a); // 25

Những thuộc tính của object o là:

Lưu ý ta dùng hàm để định nghĩa getter và setter, nhưng chúng ta truy xuất nó như một thuộc tính. Để định nghĩa một getter hoặc setter ta dùng cú pháp "[gs]et property()", Hoặc chúng ta một cách khác để định nghĩa getter hoặc setter là dùng Object.defineProperty  (hoặc dùng cách cũ với Object.prototype.__defineGetter__).

Đoạn mã sau minh họa cách dùng getter và setter mở rộng prototype của {{jsxref("Date")}} để thêm thuộc tính year cho tất cả thực thể được tạo ra từ lớp Date. Và dùng phương thức getFullYear and setFullYear để hỗ trợ getter và setter year.

Những câu lệnh sau định nghĩa getter và setter cho thuộc tính year:
 

var d = Date.prototype;
Object.defineProperty(d, 'year', {
  get: function() { return this.getFullYear(); },
  set: function(y) { this.setFullYear(y); }
});

Những câu lệnh sau sử dụng getter và setter trong đối tượng Date:
 

var now = new Date();
console.log(now.year); // 2000
now.year = 2001; // 987617605170
console.log(now);
// Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001

Điều cần ghi nhớ là, getter vad setter có thể:

Khi tạo getters và settes sử dụng bộ khởi tạo object điều bạn cần làm là đặt từ khóa  get trước tên phương thức getter và từ khóa set trước phương thức setter. Tất nhiên là phương thức getter không cần bất kỳ tham số nào, còn phương thức setter cần đúng một tham số. Như ví dụ sau:

var o = {
  a: 7,
  get b() { return this.a + 1; },
  set c(x) { this.a = x / 2; }
};

Getters and setters có thể được thêm vào một object bất kỳ khi nào sau khi được tạo bằng cách dùng phương thức Object.defineProperties. Tham số đầu tiên của phương thức này là object mà bạn muốn định nghĩa getter và setter. Tham số thứ hai là một object mà tên của thuộc tính là tên của getter và setter, giá trị của thuộc tính là object định nghĩa hàm getter và setter. Sau đây là ví dụ minh họa cách định nghĩa getter và setter

var o = { a: 0 };

Object.defineProperties(o, {
    'b': { get: function() { return this.a + 1; } },
    'c': { set: function(x) { this.a = x / 2; } }
});

o.c = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
console.log(o.b); // Runs the getter, which yields a + 1 or 6

Việc lựa chọn cách nào để định nghĩa getter và setter tùy thuộc vào phong cách lập trình và công việc cụ thể. Nếu bạn luôn dùng bộ khởi tạo object khi định nghĩa một prototype thì bạn nên chọn cách thứ nhất. Cách này đơn giản và tự nhiên. Tuy nhiên, nếu bạn cần thêm getters và setters sau đó — bởi vì bạn không viết prototype hoặc object cụ thể — bạn phải sử dụng cách thứ hai. Cách thứ hai thể hiện tính chất "động" tự nhiên của JavaScript — nhưng nó làm cho code khó đọc và khó hiểu.

Việc xóa bỏ thuộc tính

Bạn có thể xóa bỏ một thuộc tính không kế thừa bằng toán tử  delete. Câu lệnh sau chỉ bạn cách để xóa bỏ một thuộc tính.

// Creates a new object, myobj, with two properties, a and b.
var myobj = new Object;
myobj.a = 5;
myobj.b = 12;

// Removes the a property, leaving myobj with only the b property.
delete myobj.a;
console.log ('a' in myobj); // yields "false"

Bạn cũng có thể dùng delete để xóa bỏ biến toàn cục nếu bạn không dùng từ khóa var khi định nghĩa biến.

g = 17;
delete g;

So sánh objects

Trong JavaScript những object là kiểu tham chiếu. Hai đối tượng tách biệt không bao giờ bằng nhau, thậm chí nếu chúng có cùng những thuộc tính. Chỉ khi nó so sánh với chính nó thì kết quả mới là true.

// Two variables, two distinct objects with the same properties
var fruit = {name: 'apple'};
var fruitbear = {name: 'apple'};

fruit == fruitbear; // return false
fruit === fruitbear; // return false
// Two variables, a single object
var fruit = {name: 'apple'};
var fruitbear = fruit;  // assign fruit object reference to fruitbear

// here fruit and fruitbear are pointing to same object
fruit == fruitbear; // return true
fruit === fruitbear; // return true
fruit.name = 'grape';
console.log(fruitbear);    // yields { name: "grape" } instead of { name: "apple" }

Chi tiết về toán tử so sánh, xem thêm tại Comparison operators.

See also

{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}