Mã mô tả cơ sở lưu trú

Phần lớn hoạt động tương tác của bạn với các thuộc tính đối tượng có thể là ở cấp nền tảng, bao gồm cả việc tạo giá trị cố định của đối tượng cũng như cài đặt và truy cập bằng cách sử dụng khoá. Tuy nhiên, bạn có thể định cấu hình nội bộ bất kỳ thuộc tính nào của một đối tượng để kiểm soát chi tiết cách truy cập các thuộc tính đó, được thay đổi và xác định. Mỗi thuộc tính đối tượng đều có một tập hợp các thuộc tính không hiển thị chứa siêu dữ liệu được liên kết với thuộc tính đó, được gọi là "thuộc tính mô tả."

Có hai loại mã mô tả được liên kết với bất kỳ thuộc tính nào: mã mô tả dữ liệumã mô tả trình truy cập. Chỉ số mô tả dữ liệu bao gồm các cặp khoá và giá trị có chứa giá trị của một thuộc tính, bất kể giá trị đó có thể ghi, có thể định cấu hình hoặc có thể liệt kê. Chỉ số mô tả trình truy cập chứa các hàm thực thi khi một thuộc tính được đặt, thay đổi hoặc được truy cập.

Thuộc tính Loại từ ngữ mô tả Giá trị mặc định từ
Object.defineProperty()
Mô tả
[[Value]] Dữ liệu undefined Chứa giá trị của một thuộc tính.
[[Writable]] Dữ liệu false Xác định xem bạn có thể thay đổi giá trị của thuộc tính hay không.
[[Get]] Người truy cập undefined Hàm getter của thuộc tính này. Hàm này thực thi khi được truy cập.
[[Set]] Người truy cập undefined Hàm setter của thuộc tính. Hàm này thực thi khi được đặt hoặc thay đổi.
[[Configurable]] Cả hai false Nếu đây là false, thì bạn không thể xoá tài sản và không thể thay đổi. Nếu đây là false[[Writable]]true, nên giá trị của thuộc tính này có thể vẫn có thể thay đổi.
[[Enumerable]] Cả hai false Nếu giá trị này là true, bạn có thể lặp lại thuộc tính này bằng cách sử dụng Vòng lặp for...in hoặc Object.keys() tĩnh .

Mỗi thuộc tính trong số này đều sử dụng cùng một cách viết tắt là [[Prototype]], cho biết để bạn không thể truy cập trực tiếp các thuộc tính này. Thay vào đó, hãy sử dụng Phương thức tĩnh Object.defineProperty() để xác định hoặc sửa đổi các thuộc tính của một . Object.defineProperty() chấp nhận 3 đối số: đối tượng cần thao tác, khoá thuộc tính được tạo hoặc sửa đổi và một đối tượng chứa khoá (các) mã mô tả liên kết với thuộc tính đang được tạo hoặc sửa đổi.

Theo mặc định, các tài sản được tạo bằng Object.defineProperty() không thể ghi, có thể liệt kê hoặc không thể định cấu hình. Tuy nhiên, mọi tài sản mà bạn tạo dưới dạng một phần của ký hiệu đối tượng hoặc sử dụng ký hiệu dấu chấm hoặc dấu ngoặc đơn là có thể ghi, có thể liệt kê và có thể định cấu hình.

const myObj = {};

Object.defineProperty(myObj, 'myProperty', {
  value: true,
  writable: false
});

myObj.myProperty;
> true

myObj.myProperty = false;

myObj.myProperty;
> true

Ví dụ: khi [[Writable]] có giá trị false, cố gắng đặt một giá trị mới cho thuộc tính được liên kết không hoạt động tự động bên ngoài chế độ nghiêm ngặt và gửi ra lỗi ở chế độ nghiêm ngặt:

{
    const myObj = {};

    Object.defineProperty(myObj, 'myProperty', {
    value: true,
    writable: false
    });

    myObj.myProperty = false;
    myObj.myProperty;
}
> true

(function () {
    "use strict";
    const myObj = {};

    Object.defineProperty(myObj, 'myProperty', {
    value: true,
    writable: false
    });

    myObj.myProperty = false;
    myObj.myProperty;
}());\
> Uncaught TypeError: "myProperty" is read-only

Sử dụng hiệu quả các chỉ số mô tả là một khái niệm khá tiên tiến, nhưng việc hiểu cấu trúc bên trong của một đối tượng là điều cần thiết để hiểu các cú pháp liên quan khi làm việc với đối tượng theo những cách phổ biến hơn. Ví dụ: các khái niệm này phát huy tác dụng khi sử dụng phương thức tĩnh Object.create(), giúp bạn kiểm soát chi tiết mọi nguyên mẫu đi kèm với phiên bản mới .

Object.create() tạo một đối tượng mới bằng cách sử dụng một đối tượng hiện có làm đối tượng nguyên mẫu. Việc này cho phép đối tượng mới kế thừa các thuộc tính và phương thức của một đối tượng khác đối tượng do người dùng xác định giống như cách các đối tượng kế thừa các thuộc tính Nguyên mẫu Object tích hợp sẵn của JavaScript. Khi bạn gọi Object.create() bằng một đối tượng làm đối số, nó sẽ tạo một đối tượng trống với đối tượng được truyền dưới dạng nguyên mẫu của nó.

const myCustomPrototype = {
  'myInheritedProp': 10
};

const newObject = Object.create( myCustomPrototype );

newObject;
> Object {  }
<prototype>: Object { myInheritedProp: 10 }
  myInheritedProp: 10
  <prototype>: Object { … }

Object.create có thể lấy đối số thứ hai chỉ định các thuộc tính riêng cho đối tượng mới được tạo bằng cú pháp tương tự như Object.defineProperty()— tức là các khoá ánh xạ đối tượng đến một tập hợp các thuộc tính chỉ số mô tả:

const myCustomPrototype = {
  'myInheritedProp': 10
};

const myObj = Object.create( myCustomPrototype, {
        myProperty: {
            value: "The new property value.",
            writable: true,
            configurable: true
        }
  });

myObj;
> Object { … }
    myProperty: "The new property value."
    <prototype>: Object { myInheritedProp: 10 }

Trong ví dụ này, đối tượng mới (myObj) sử dụng giá trị cố định của một đối tượng (myCustomPrototype) làm nguyên mẫu, bản thân nó chứa hàm kế thừa Object.prototype, tạo ra một loạt nguyên mẫu kế thừa có tên là chuỗi nguyên mẫu. Mỗi đối tượng đều có một nguyên mẫu, cho dù được chỉ định hay kế thừa, có một nguyên mẫu được chỉ định hoặc kế thừa nguyên mẫu của riêng mình. Chuỗi này kết thúc tại null nguyên mẫu, không có nguyên mẫu của riêng mình.

const myPrototype = {
  'protoProp': 10
};

const newObject = Object.setPrototypeOf( { 'objProp' : true }, myPrototype );

newObject;
> Object { objProp: true }
    objProp: true
    <prototype>: Object { protoProp: 10 }
        protoProp: 10
        <prototype>: Object { … }

Các thuộc tính có trong nguyên mẫu của một giá trị có sẵn ở "cấp cao nhất" của một đối tượng mà không cần truy cập trực tiếp vào thuộc tính nguyên mẫu:

const objectLiteral = {
    "value" : true
};

objectLiteral;
> Object { value: true }
    value: true
    <prototype>: Object { … }

objectLiteral.toString();
"[object Object]"

Mẫu này giữ đúng cho toàn bộ chuỗi nguyên mẫu được liên kết với một đối tượng: khi cố gắng truy cập vào một thuộc tính, trình thông dịch sẽ tìm thuộc tính đó thuộc tính ở mỗi "cấp" của chuỗi nguyên mẫu, từ trên xuống dưới, cho đến khi tìm tài sản hoặc kết thúc chuỗi:

const myCustomPrototype = {
  'protoProp': "Prototype property value."
};

const myObj = Object.create( myCustomPrototype, {
    myProperty: {
        value: "Top-level property value.",
        writable: true,
        configurable: true
    }
});

myObj.protoProp;
> "Prototype property value."

Kiểm tra kiến thức

Chỉ số mô tả nào là trình truy cập?

[[Get]]
[[Set]]
[[Writable]]