Làm việc với các đối tượng trong JavaScript: lý thuyết và thực hành. Làm việc với các đối tượng trong javascript - Sử dụng hàm - Lý thuyết và thực hành. Đối tượng trong JavaScript là gì và nó có những khả năng gì?

Đối tượng là nền tảng của JavaScript. Nhiều kiểu dữ liệu tích hợp được biểu diễn dưới dạng đối tượng. Để trở thành nhà phát triển JavaScript thành công, bạn cần hiểu rõ về cách chúng hoạt động. Các khối xây dựng của một đối tượng được gọi là các trường hoặc thuộc tính đối tượng JavaScript của nó. Chúng được sử dụng để mô tả bất kỳ khía cạnh nào của một đối tượng. Thuộc tính có thể mô tả độ dài của danh sách, màu bầu trời hoặc ngày sinh của một người. Tạo các đối tượng là một quá trình dễ dàng. Ngôn ngữ này cung cấp một cú pháp được gọi là đối tượng bằng chữ, được biểu thị bằng dấu ngoặc nhọn.

Truy cập thuộc tính

Ngôn ngữ này cung cấp hai mục để truy cập các thuộc tính. Đầu tiên và phổ biến nhất được gọi là ký hiệu dấu chấm. Trong ký hiệu dấu chấm, một tài nguyên có thể được truy cập bằng cách chỉ định tên đối tượng máy chủ, theo sau là dấu chấm và tên thuộc tính. Ví dụ: khi object.foo ban đầu được đặt thành 1 thì giá trị của nó sẽ trở thành 2 sau khi thực thi câu lệnh đối tượng JavaScript.

Một cú pháp truy cập thay thế được gọi là ký hiệu khung. Trong ký hiệu, tên đối tượng được theo sau bởi một bộ dấu ngoặc vuông. Trong đó, tên thuộc tính được chỉ định dưới dạng chuỗi:

đối tượng["foo"] = đối tượng["foo"] + 1.

Nó có tính biểu cảm cao hơn ký hiệu dấu chấm vì nó cho phép một biến chỉ định tất cả hoặc một phần tên thuộc tính. Điều này có thể thực hiện được vì trình thông dịch đối tượng JavaScript tự động chuyển đổi biểu thức này thành một chuỗi rồi lấy thuộc tính tương ứng. Tên thuộc tính được tạo nhanh chóng bằng cách nối nội dung của biến f với chuỗi "oo":

đối tượng = "thanh".

Ký hiệu ngoặc cho phép tên thuộc tính chứa các ký tự bị cấm trong ký hiệu dấu chấm. Ví dụ: tuyên bố sau đây hoàn toàn hợp pháp trong ngoặc đơn. Tuy nhiên, nếu người dùng cố gắng tạo cùng tên thuộc tính theo ký hiệu dấu chấm, họ sẽ gặp phải lỗi cú pháp:

object["!@#$% &*()."] = true.

Các thuộc tính của các đối tượng JavaScript lồng nhau có thể được truy cập bằng cách nối chuỗi các dấu chấm và/hoặc dấu ngoặc đơn. Ví dụ: đối tượng sau chứa một đối tượng lồng nhau có tên baz chứa một đối tượng khác có tên foo có thuộc tính có tên bar chứa giá trị năm:

var object = ( baz: ( foo: ( bar: 5 ) ) ).

Các biểu thức sau đây truy cập vào thuộc tính đính kèm thanh. Biểu thức đầu tiên sử dụng ký hiệu dấu chấm, trong khi biểu thức thứ hai sử dụng ký hiệu hình vuông. Biểu thức thứ ba kết hợp cả hai mục để đạt được cùng một kết quả:

  • object.baz.foo.bar;
  • object["baz"]["foo"]["bar"];
  • object["baz"].foo["bar"].

Các biểu thức như trong ví dụ trước có thể làm giảm hiệu suất nếu sử dụng không đúng cách và khiến đối tượng JavaScript bị lỗi. Việc đánh giá từng biểu thức dấu chấm hoặc dấu ngoặc cần có thời gian. Nếu cùng một thuộc tính được sử dụng nhiều lần thì việc truy cập thuộc tính đó một lần rồi lưu giá trị vào một biến cục bộ cho tất cả các lần sử dụng trong tương lai là điều hợp lý.

Chức năng như phương thức

Khi một hàm được sử dụng làm thuộc tính của một đối tượng, nó được gọi là một phương thức. Giống như các thuộc tính, chúng được chỉ định trong ký hiệu chữ đối tượng. Ví dụ:

var object = ( sum: function(foo, bar) ( return foo + bar; ) ).

Các phương thức đối tượng JavaScript có thể được gọi bằng cách sử dụng dấu và dấu ngoặc đơn. Ví dụ sau gọi phương thức sum() từ ví dụ trước bằng cách sử dụng cả hai mục:

  • object.sum(1, 2);
  • đối tượng["tổng"](1, 2).

Ký hiệu chữ đối tượng rất hữu ích cho việc tạo đối tượng mới, nhưng nó không thể thêm thuộc tính hoặc phương thức vào đối tượng hiện có. May mắn thay, việc thêm dữ liệu mới cũng dễ dàng như tạo một câu lệnh gán. Một đối tượng trống được tạo ra. Sau đó, bằng cách sử dụng toán tử gán, chúng ta thêm hai thuộc tính, foo, bar và phương thức baz:

  • đối tượng var = ();
  • object.foo = 1;
  • object.bar = null;
  • object.baz = function() ( return "hello from baz()"; ).
Đóng gói chương trình

Ý tưởng cơ bản của lập trình hướng đối tượng là chia chương trình thành các phần nhỏ hơn và để mỗi phần chịu trách nhiệm quản lý trạng thái của chính nó. Vì vậy, một số kiến ​​thức về cách hoạt động của một phần của chương trình có thể mang tính cục bộ đối với phần đó. Ai đó đang thực hiện phần còn lại của chương trình sẽ không nhớ hoặc thậm chí không biết về nó. Bất cứ khi nào dữ liệu cục bộ này thay đổi, chỉ cần cập nhật mã ngay xung quanh nó.

Các phần khác nhau của một chương trình tương tác với nhau thông qua các giao diện, bộ giới hạn các hàm hoặc ràng buộc cung cấp chức năng hữu ích ở mức độ trừu tượng hơn trong khi ẩn cách triển khai chính xác của chúng. Những phần như vậy của chương trình được mô hình hóa bằng cách sử dụng các đối tượng. Giao diện của chúng bao gồm một tập hợp các phương thức và thuộc tính cụ thể. Các thuộc tính là một phần của giao diện được gọi là công khai. Phần còn lại, không chạm vào mã bên ngoài, được gọi là riêng tư.

Nhiều ngôn ngữ cung cấp khả năng phân biệt giữa thuộc tính công khai và riêng tư và không cho phép mã bên ngoài truy cập vào thuộc tính riêng tư. JavaScript, một lần nữa áp dụng cách tiếp cận tối giản, vẫn chưa xuất hiện. Công việc hiện đang được tiến hành để thêm ngôn ngữ này. Vì vậy, các lập trình viên JavaScript sẽ sử dụng thành công ý tưởng này. Thường xuyên, giao diện có thể truy cậpđược mô tả trong tài liệu hoặc nhận xét. Thông thường, người ta cũng đặt dấu gạch dưới (_) ở đầu tên thuộc tính để cho biết thuộc tính đó là riêng tư. Tách giao diện khỏi việc thực hiện là một ý tưởng tuyệt vời. Điều này thường được gọi là đóng gói.

Của cải

Một đối tượng có dấu ngoặc đơn (...) được gọi là một đối tượng theo nghĩa đen. Bạn có thể đặt ngay một số thuộc tính trong dấu ngoặc như vậy (...). Ví dụ: cặp “khóa: giá trị, v.v.”:

let user = ( // tên đối tượng: "John", // theo key "name" lưu trữ giá trị "John" age: 30 // by key "age" store value 30 }.!}

Một thuộc tính có một khóa (còn được gọi là "tên" hoặc "mã định danh") trước dấu hai chấm :// và một giá trị ở bên phải của nó. Đối tượng người dùng có hai thuộc tính. Đối tượng JavaScript của người dùng thu được có hai tệp đã ký được gắn nhãn "tên" và "tuổi". Bạn có thể thêm, xóa và đọc các tập tin từ nó bất cứ lúc nào. Giá trị thuộc tính được truy cập bằng ký hiệu dấu chấm. Nó có thể thuộc bất kỳ loại nào. Bạn có thể thêm một giá trị boolean. Để xóa thuộc tính, hãy sử dụng xóa trong trường hợp Lỗi của đối tượng JavaScript.

Tất cả các đối tượng lỗi JavaScript đều là hậu duệ của đối tượng Lỗi hoặc đối tượng được kế thừa:

  • Đối tượng Lỗi Cú pháp kế thừa từ đối tượng Lỗi.
  • Lỗi phân tích cú pháp JSON của một loại đối tượng Lỗi Cú pháp nhất định.
  • Để tìm hiểu sâu hơn về cách các ứng dụng xử lý Lỗi JavaScript, hãy làm quen tốt hơn với Airbrake JavaScript - một công cụ theo dõi lỗi để cảnh báo theo thời gian thực và thông tin chi tiết tức thì về những gì đã xảy ra với mã JavaScript của bạn.

    Thông báo lỗi mà người dùng có thể nhận được trước khi xóa đối tượng JavaScript:

  • Ký tự điều khiển không hợp lệ trong một chuỗi ký tự.
  • Ký tự xấu trong một chuỗi ký tự.
  • Đầu ra Unicode xấu.
  • Nhân vật thoát tệ.
  • Chuỗi không kết thúc.
  • Mã không phải số không mong đợi.
  • Không có số nào sau dấu thập phân.
  • Số phân số không kết thúc.
  • Không có con số nào sau chỉ báo độ.
  • Không có số nào sau dấu mũ.
  • Phần mũ không có số.
  • Kết thúc dữ liệu bất ngờ.
  • Không ngờ tới từ khóa.
  • Một biểu tượng bất ngờ.
  • Kết thúc dữ liệu khi đọc nội dung của một đối tượng.
  • Tên thuộc tính dự kiến ​​hoặc ")".
  • Tính chất tính toán

    Bạn có thể sử dụng dấu ngoặc vuông trong một đối tượng bằng chữ. Chúng được gọi là thuộc tính tính toán. Một ví dụ được đưa ra dưới đây.

    Ý nghĩa của thuộc tính được tính toán rất đơn giản: nó có nghĩa là tên thuộc tính phải được lấy từ Fruit. Vì vậy, nếu khách nhập "quả táo", túi sẽ trở thành (táo: 5). Bạn có thể sử dụng các biểu thức phức tạp hơn trong ngoặc vuông:

    để trái cây = "táo";

    : 5 // bag.appleComputers = 5

    Dấu ngoặc vuông mạnh hơn nhiều so với ký hiệu dấu chấm. Chúng cho phép tên thuộc tính và biến. Nhưng chúng cũng cồng kềnh hơn để viết. Vì vậy, hầu hết khi tên thuộc tính được biết đến và đơn giản, dấu chấm sẽ được sử dụng. Và nếu bạn cần thứ gì đó phức tạp hơn thì hãy chuyển sang dấu ngoặc vuông.

    bảo lưu từ

    Một biến không thể có tên bằng một trong các từ dành riêng như "for", "let", "return", v.v. Nhưng khi sắp xếp các đối tượng JavaScript thì không có hạn chế nào như vậy.


    Về nguyên tắc, bất kỳ tên nào cũng được cho phép, nhưng có một tên đặc biệt: "__proto__" được đối xử đặc biệt vì lý do lịch sử. Ví dụ: bạn không thể đặt nó thành một giá trị khác ngoài một đối tượng:

    obj.__proto__ = 5;

    cảnh báo(obj.__proto__); // không hoạt động như dự định

    Như bạn có thể thấy từ đoạn mã, mục đích của số nguyên thủy 5 bị bỏ qua. Đây có thể là nguồn gốc của lỗi và thậm chí là lỗ hổng bảo mật nếu người vận hành có ý định lưu trữ các cặp khóa-giá trị tùy ý trong một đối tượng và cho phép khách truy cập chỉ định khóa. Trong trường hợp này, khách truy cập có thể chọn "proto" làm khóa và thêm JavaScript vào đối tượng. Có một cách để biến các đối tượng được xử lý bằng __proto__ thành một thuộc tính thông thường. Ngoài ra còn có một bản đồ cấu trúc dữ liệu khác hỗ trợ các khóa tùy ý.

    Thuộc tính số nguyên

    Thuật ngữ "thuộc tính số nguyên" ở đây có nghĩa là một chuỗi có thể được chuyển đổi từ một số nguyên mà không cần sửa đổi. Vì vậy, ví dụ: "49" là tên thuộc tính số nguyên vì khi nó được chuyển đổi thành số nguyên và quay lại, nó vẫn giống nhau. Nhưng “+49” và “1.2” thì không như vậy. Mặt khác, nếu các khóa không phải là số nguyên thì chúng sẽ được liệt kê theo thứ tự được tạo. Ví dụ dưới đây.


    Để khắc phục sự cố với mã quay số, bạn có thể "gian lận" bằng cách làm cho mã không đầy đủ. Thêm dấu "+" (dấu cộng) trước mỗi mã là đủ. Bây giờ nó sẽ hoạt động như dự định.

    Sự khác biệt giữa các đối tượng và nguyên thủy là chúng được lưu trữ và sao chép “bằng cách tham chiếu”. Các giá trị nguyên thủy được gán và sao chép "dưới dạng giá trị số nguyên". Một biến lưu trữ một "địa chỉ trong bộ nhớ" chứ không phải chính đối tượng đó hoặc một "tham chiếu" đến nó. Bạn có thể sử dụng bất kỳ biến nào để truy cập và thay đổi nội dung của nó.


    Ví dụ trên cho thấy chỉ có một đối tượng và quản trị viên đăng nhập vào đó. Sau đó, nếu sau này sử dụng một khóa (người dùng) khác, người dùng sẽ nhận thấy những thay đổi.

    Các toán tử đẳng thức == và đẳng thức nghiêm ngặt === cho các đối tượng hoạt động theo cùng một cách. Hai đối tượng chỉ bằng nhau nếu chúng là cùng một đối tượng. Để so sánh như obj1 > obj2 hoặc so sánh với obj nguyên thủy == 5, các đối tượng được chuyển đổi thành đối tượng nguyên thủy. Thành thật mà nói, những so sánh như vậy rất hiếm khi cần thiết và thường là kết quả của lỗi mã hóa.

    Xác thực đối tượng JavaScript

    Các đối tượng có quyền truy cập vào bất kỳ tài sản nào. Tuy nhiên, nếu nó hoàn toàn không tồn tại thì đó không phải là lỗi. Chỉ truy cập một thuộc tính không tồn tại sẽ trả về không xác định. Nó cung cấp một cách rất phổ biến để kiểm tra một thuộc tính và so sánh nó với một thuộc tính không xác định. Dưới đây là một ví dụ.


    Sử dụng "in" cho các thuộc tính lưu trữ không xác định. Thông thường, kiểm tra so sánh "=== không xác định" nghiêm ngặt hoạt động tốt. Ăn một trường hợp đặc biệt khi nó thất bại và "trong" hoạt động chính xác. Đây là khi một thuộc tính của một đối tượng tồn tại nhưng vẫn chưa được xác định.


    Trong đoạn mã trên, về mặt kỹ thuật tồn tại thuộc tính obj.test. Do đó, toán tử in hoạt động chính xác. Những tình huống như thế này rất hiếm vì không xác định thường không được chỉ định. Các giá trị null "không xác định" hoặc "trống" chủ yếu được sử dụng. Do đó, toán tử in thực sự là một khách trong mã.

    vòng lặp "for..in"

    Để điều hướng qua tất cả các phím từ đối tượng này sang đối tượng khác, có hình thức đặc biệt vòng lặp: for..in. Đây là một điều hoàn toàn khác với cấu trúc for(;;).

    Dưới đây là một ví dụ.


    Xin lưu ý rằng tất cả các hàm tạo “for” đều cho phép bạn khai báo một biến vòng lặp bên trong vòng lặp dưới dạng khóa let. Ngoài ra, bạn có thể sử dụng tên biến, khóa khác để thay thế.

    Ví dụ, for(let prop in obj) cũng được sử dụng rộng rãi.

    Có một "dấu ngoặc vuông" thay thế hoạt động với bất kỳ chuỗi nào.


    Vấn đề ở đây yêu cầu các khóa của đối tượng JavaScript phải là một mã định danh biến hợp lệ, nghĩa là không có khoảng trắng hoặc các hạn chế khác. Phải cẩn thận để đảm bảo rằng dòng bên trong dấu ngoặc được trích dẫn chính xác. Dấu ngoặc vuông cũng cung cấp một cách để lấy tên thuộc tính từ kết quả của bất kỳ biểu thức nào, trái ngược với chuỗi ký tự từ một biến:

    let key = "thích chim";

    // giống như user["like chim"] = true;

    người dùng = đúng.

    Ở đây, biến khóa có thể được tính toán trong thời gian chạy và tùy thuộc vào thông tin đầu vào của người dùng, sau đó được sử dụng để truy cập thuộc tính. Điều này giúp các lập trình viên linh hoạt hơn. Ký hiệu dấu chấm không thể được sử dụng theo cách tương tự, vì nó sẽ lặp lại đối tượng JavaScript. Dưới đây là một ví dụ.


    Đối tượng hằng

    Một đối tượng const được khai báo có thể được sửa đổi. Một ví dụ được đưa ra dưới đây.


    Có vẻ như đối tượng JavaScript ở dòng (*) sẽ báo lỗi, nhưng thực tế không phải vậy. Điều này là do const nắm bắt giá trị của chính người dùng. Và ở đây người dùng luôn luôn tham chiếu đến cùng một đối tượng. Dòng (*) đi vào bên trong đối tượng, không được gán lại cho người dùng. Const sẽ báo lỗi nếu bạn cố gắng đặt người dùng và thứ gì đó khác. Nhân bản và hợp nhất, Object.sign tạo một tham chiếu khác đến cùng một đối tượng nếu nó cần được sao chép. Điều này cũng có thể thực hiện được nhưng khó hơn một chút vì JavaScript không có phương thức tích hợp sẵn. Trên thực tế, điều này hiếm khi cần thiết. Sao chép bằng tham chiếu được sử dụng trong hầu hết các trường hợp. Nhưng nếu bạn thực sự cần điều này, thì bạn cần tạo một đối tượng JavaScript và sao chép cấu trúc của một đối tượng hiện có, sao chép các thuộc tính của nó ở mức nguyên thủy. Dưới đây là một ví dụ.


    Và bạn cũng có thể sử dụng phương thức Object.sign cho việc này. Các đối số dest và src1, ..., srcN là các đối tượng. Nó sao chép thuộc tính của tất cả các đối tượng src1, ..., srcNINTO dest. Nói cách khác, thuộc tính của tất cả các đối số, bắt đầu từ đối số thứ hai, sẽ được sao chép sang đối số thứ nhất. Sau đó nó trở về đích. Ví dụ: bạn có thể sử dụng nó để kết hợp nhiều đối tượng thành một.


    Và bạn cũng có thể sử dụng Object.sign để thay thế vòng lặp nhân bản đơn giản. Nó sao chép tất cả thuộc tính của người dùng vào một đối tượng trống và trả về nó, giống như một vòng lặp, nhưng ngắn hơn. Cho đến nay, người ta vẫn giả định rằng tất cả các thuộc tính của người dùng đều là nguyên thủy. Nhưng các thuộc tính có thể là tham chiếu đến các đối tượng khác.

    Để khắc phục điều này, bạn cần sử dụng vòng lặp nhân bản để kiểm tra từng giá trị người dùng và nếu đó là một đối tượng thì sẽ sao chép cấu trúc của nó. Điều này được gọi là "nhân bản sâu".

    Có một thuật toán nhân bản sâu tiêu chuẩn để xử lý trường hợp trên và các trường hợp phức tạp hơn được gọi là thuật toán nhân bản có cấu trúc. Để tránh phải phát minh lại bánh xe, bạn có thể sử dụng cách triển khai đang hoạt động từ thư viện JavaScript lodash, phương thức này được gọi là _.cloneDeep(obj).

    Phương pháp nâng cao

    Nếu một lập trình viên lặp lại một đối tượng và muốn lấy tất cả các thuộc tính theo đúng thứ tự chúng được thêm vào, anh ta có thể dựa vào "thứ tự đặc biệt", trong đó các thuộc tính số nguyên được sắp xếp và các thuộc tính khác được hình thành theo thứ tự mà đối tượng JavaScript được tạo .

    Các phương thức đối tượng nâng cao xử lý các khái niệm hiếm khi được sử dụng trong JavaScript. Điều này là do trong các tình huống thông thường, những tính năng mạnh mẽ này không cần thiết. Một số phương pháp này có thể không hoạt động trong các trình duyệt cũ hơn, chẳng hạn như các bản phát hành đầu tiên của Netscape 4.

    Nguyên mẫu có thể được sử dụng để tạo các đối tượng JavaScript và tất cả các phương thức mycircle, không chỉ các phương thức mới. Điều này có tác động hiệu suất hỗn hợp. Chúng không phải lưu trữ các bản sao phương thức riêng biệt cho từng phiên bản đối tượng, do đó, chúng có thể cần ít bộ nhớ hơn để hoạt động, nhưng trình duyệt phải tìm phạm vi hiện tại và phạm vi gốc để tìm thấy chúng. Điều này có thể dẫn đến độ trễ cực cao. Nói chung, người dùng nên sử dụng những gì phù hợp với mã thay vì đưa ra quyết định dựa trên hiệu suất, trừ khi họ đang xử lý một môi trường được kiểm soát rất cụ thể.


    Trả về đúng

    Trong một số trường hợp, có thể cần phải có thuộc tính của đối tượng được liên kết với chính đối tượng đó hoặc ở đâu đó trong chuỗi nguyên mẫu. Trong JavaScript, tất cả các đối tượng đều sử dụng phương thức hasOwnProperty, phương thức này trả về true nếu thuộc tính đó được liên kết với thể hiện đối tượng riêng biệt. Trong trường hợp này, có thể kiểm tra xem hàm tạo của một đối tượng có cùng thuộc tính với cùng giá trị với chính thể hiện của đối tượng hay không. Điều này có thể cho kết quả không chính xác nếu có các thuộc tính đối tượng JavaScript riêng biệt có cùng giá trị cho cả phiên bản đối tượng và nguyên mẫu mạch. Phương thức hasOwnProperty nhận một tham số duy nhất - tên thuộc tính dưới dạng một chuỗi.


    Bạn có thể tạo các phương thức riêng tư theo cách tương tự. Nó chỉ đơn giản là một hàm được tạo bên trong hàm khởi tạo. Điều này có vẻ khó hiểu với một số người, nhưng đó là cách nó hoạt động. Một hàm riêng chỉ có thể được gọi bởi chính hàm tạo hoặc bởi các phương thức được xác định trên dòng. Chúng có thể được sử dụng làm phương thức công khai nếu được gán cho một hàm tạo công khai và được truy cập bằng các phương thức công khai của đối tượng Javascript.

    hàm myob() ( hàm cantBeSeen() ( cảnh báo(secretValue);

    ) var secretValue = "";

    this.method1 = function () ( secretValue = "không có gì ngạc nhiên";!}

    this.method2 = cantBeSeen;

    ) var oneOb = new myob();

    oneOb.method1();

    //cảnh báo "không có gì bất ngờ" oneOb.method2();

    //cảnh báo "không có gì bất ngờ".

    Mẫu lệnh

    Các đối tượng lệnh cho phép các hệ thống được ghép nối lỏng lẻo bằng cách tách biệt những hệ thống đưa ra yêu cầu khỏi các đối tượng và những hệ thống thực sự xử lý yêu cầu. Những yêu cầu này được gọi là sự kiện và mã xử lý yêu cầu đó được gọi là trình xử lý sự kiện.

    Giả sử bạn đang tạo các ứng dụng hỗ trợ các thao tác Cắt, Sao chép và Dán trong bảng nhớ tạm. Những hành động này có thể được kích hoạt theo nhiều cách khác nhau trong suốt ứng dụng: bằng hệ thống menu, bằng menu ngữ cảnh, ví dụ bằng cách nhấp chuột phải vào trương Văn bản hoặc một phím tắt. Các đối tượng lệnh cho phép bạn tập trung xử lý các hành động này, một lệnh cho mỗi thao tác, khi chỉ cần một lệnh để xử lý tất cả các yêu cầu Cắt, một lệnh cho tất cả các yêu cầu Sao chép và một lệnh cho tất cả các yêu cầu Dán.

    Vì các nhóm tập trung tất cả quá trình xử lý nên họ cũng thường tham gia xử lý các chức năng hoàn tác cho toàn bộ ứng dụng. Những cải tiến đáng kể có thể đạt được thông qua việc sử dụng công nghệ hiện đại Phương thức JavaScript dẫn đến các ứng dụng hiệu quả hơn, đáng tin cậy hơn và có thể bảo trì được.

    Để tìm hiểu cách thực hiện việc này, bạn có thể sử dụng các mẫu JavaScript + jQuery. Gói độc đáo này bao gồm JavaScript được tối ưu hóa cho tất cả các mẫu GoF sử dụng các tính năng nâng cao hơn như không gian tên, nguyên mẫu, mô-đun, đối tượng hàm, phần đóng, hàm ẩn danh, v.v. Nếu người dùng cần các công cụ và kỹ thuật mới nhất cho mẫu JavaScript, mẫu jQuery và kiến ​​trúc mẫu thì đây sự lựa chọn tốt nhất sử dụng. Gói này chứa đựng giá trị, thông tin cập nhập dành cho các nhà phát triển JavaScript. Đây là những gì được bao gồm:

  • Các mẫu GoF được tối ưu hóa cho JavaScript.
  • Các mẫu thiết kế JavaScript hiện đại.
  • Các mẫu thiết kế Model-View.
  • Mẫu thiết kế jQuery.
  • Các mẫu kiến ​​trúc của thành ngữ JavaScript.
  • Các ứng dụng ví dụ (MVC, SPA, v.v.)
  • Những kiến ​​thức cơ bản được đề xuất về cú pháp đối tượng JavaScript là rất quan trọng đối với những người mới bắt đầu lập trình. Đầu tiên phải hiểu đối tượng thì mới có kiến ​​thức về lập trình hướng đối tượng. Điều cực kỳ quan trọng là phải hiểu sâu sắc về tài liệu này vì nó đóng vai trò là nền tảng cho phần còn lại của tài liệu. Ngôn ngữ JavaScript.

    Các đối tượng

    Đối tượng là một kiểu dữ liệu cơ bản trong ngôn ngữ JavaScript. Một đối tượng là một giá trị tổng hợp: nó kết hợp một tập hợp các giá trị (giá trị đơn giản hoặc các đối tượng khác) và cho phép các giá trị đó được lưu trữ và truy xuất theo tên.

    Một đối tượng là một tập hợp các thuộc tính không có thứ tự, mỗi thuộc tính có một tên và một giá trị. Tên thuộc tính là các chuỗi, vì vậy có thể nói các đối tượng ánh xạ chuỗi tới các giá trị. Việc ánh xạ chuỗi tới giá trị này có thể có nhiều tên: Bạn có thể đã quen thuộc với cấu trúc dữ liệu cơ bản như hàm băm, từ điển hoặc mảng kết hợp. Tuy nhiên, đối tượng có nhiều thứ hơn là việc ánh xạ đơn giản các chuỗi tới các giá trị.

    Ngoài các thuộc tính riêng, các đối tượng JavaScript cũng có thể kế thừa các thuộc tính từ các đối tượng khác, được gọi là nguyên mẫu. Các phương thức đối tượng là đại diện điển hình của các thuộc tính được kế thừa và "kế thừa thông qua nguyên mẫu" là một tính năng chính của ngôn ngữ JavaScript.

    Các đối tượng trong JavaScript là động—chúng thường cho phép bạn thêm và xóa các thuộc tính—nhưng chúng cũng có thể được sử dụng để mô phỏng các đối tượng tĩnh và “cấu trúc” được tìm thấy trong các ngôn ngữ lập trình kiểu tĩnh. Chúng cũng có thể được sử dụng (nếu bạn bỏ qua việc ánh xạ các đối tượng đó thành giá trị) để biểu diễn các tập hợp chuỗi.

    Bất kỳ giá trị nào trong JavaScript không phải là chuỗi, số, đúng, sai, null hoặc không xác định đều là một đối tượng. Và ngay cả các chuỗi, số và boolean không phải là đối tượng cũng có thể hoạt động giống như các đối tượng bất biến (có các đối tượng trình bao bọc Chuỗi, Số, v.v.).

    Đối tượng là giá trị có thể thay đổi và các thao tác trên chúng được thực hiện bằng tham chiếu chứ không phải bằng giá trị. Nếu biến x tham chiếu đến một đối tượng và câu lệnh var y = x; , biến y sẽ chứa tham chiếu đến cùng một đối tượng chứ không phải bản sao của đối tượng đó. Bất kỳ thay đổi nào được thực hiện đối với đối tượng bởi biến y cũng sẽ được phản ánh trong biến x.

    Một thuộc tính có tên và giá trị. Tên thuộc tính có thể là bất kỳ chuỗi nào, kể cả chuỗi trống, nhưng một đối tượng không thể có hai thuộc tính có cùng tên. Giá trị thuộc tính có thể là bất kỳ giá trị nào được phép trong ngôn ngữ JavaScript hoặc (trong ECMAScript 5) một hàm đọc hoặc ghi (hoặc cả hai).

    Ngoài tên và giá trị, mỗi thuộc tính còn có một số giá trị liên kết với nó, được gọi là thuộc tính tài sản :

      Thuộc tính có thể ghi xác định xem giá trị thuộc tính có thể ghi hay không.

      Thuộc tính liệt kê xác định xem tên thuộc tính có sẵn để liệt kê trong vòng lặp for/in hay không.

      Thuộc tính có thể cấu hình xác định khả năng cấu hình, tức là. xóa một thuộc tính và thay đổi thuộc tính của nó.

    Trước khi tiêu chuẩn ECMAScript 5 ra đời, tất cả các thuộc tính trong đối tượng được tạo bởi một chương trình đều có thể ghi, liệt kê và định cấu hình. ECMAScript 5 cung cấp khả năng tùy chỉnh các thuộc tính thuộc tính của bạn.

    Ngoài các thuộc tính, mỗi đối tượng còn có ba thuộc tính đối tượng :

      Thuộc tính lớp chứa một chuỗi có tên lớp của đối tượng và chỉ định loại đối tượng.

      Cờ mở rộng (trong ECMAScript 5) cho biết khả năng thêm thuộc tính mới vào một đối tượng.

    Cuối cùng, bên dưới là mô tả một số thuật ngữ sẽ giúp chúng ta phân biệt giữa ba loại đối tượng rộng rãi trong JavaScript và hai loại thuộc tính:

    Một đối tượng ngôn ngữ cơ bản

    Nó là một đối tượng hoặc lớp đối tượng được xác định bởi đặc tả ECMAScript. Mảng, hàm, ngày tháng và biểu thức chính quy(ví dụ) là các đối tượng của ngôn ngữ cơ sở.

    Đối tượng thời gian chạy

    Đây là một đối tượng được xác định bởi môi trường thời gian chạy (chẳng hạn như trình duyệt web) trong đó trình thông dịch JavaScript được nhúng. Các đối tượng HTMLElement, đại diện cho cấu trúc của một trang web bằng JavaScript phía máy khách, là các đối tượng thời gian chạy. Các đối tượng thời gian chạy cũng có thể là các đối tượng ngôn ngữ cơ sở, ví dụ khi bộ thực thi định nghĩa các phương thức đồ vật thông thường Chức năng của ngôn ngữ JavaScript cơ bản.

    Đối tượng tùy chỉnh

    Bất kỳ đối tượng nào được tạo bằng cách thực thi mã JavaScript.

    Sở hữu tài sản

    Đây là một thuộc tính được xác định trực tiếp trên một đối tượng nhất định.

    Tài sản thừa kế

    Đây là thuộc tính được xác định bởi nguyên mẫu của đối tượng.

    Tạo đối tượng

    Các đối tượng có thể được tạo bằng cách sử dụng các ký tự đối tượng, từ khóa mới và (trong ECMAScript 5) hàm Object.create().

    Đối tượng bằng chữ

    Cách đơn giản nhất để tạo một đối tượng là đưa một đối tượng vào trong chương trình của bạn. Một đối tượng bằng chữ là một danh sách các thuộc tính (cặp tên/giá trị) được phân tách bằng dấu phẩy được đặt trong dấu ngoặc nhọn. Tên thuộc tính có thể là một mã định danh hoặc một chuỗi ký tự (chuỗi trống có thể được chấp nhận). Giá trị của một thuộc tính có thể là bất kỳ biểu thức nào được phép trong JavaScript - giá trị của biểu thức (đây có thể là một giá trị đơn giản hoặc một đối tượng) sẽ trở thành giá trị của thuộc tính.

    Dưới đây là một số ví dụ về tạo đối tượng:

    Var trống = (); // Đối tượng không có thuộc tính var point = ( x:0, y:0 ); // Hai thuộc tính var point2 = ( x:point.x, y:point.y+1 ); // Các giá trị phức tạp hơn var site = ( "url site": "www..NET Framework", // và dấu gạch nối, vì vậy hãy sử dụng dấu ngoặc kép tác giả: ( // Giá trị của thuộc tính này là firstname: "Alexandr", / / object. Xin lưu ý rằng họ: "Frolov" // tên của các thuộc tính này không có dấu ngoặc kép) );

    ECMAScript 5 (và một số triển khai ECMAScript 3) cho phép sử dụng các từ dành riêng làm tên thuộc tính mà không có dấu ngoặc kép. Tuy nhiên, nói chung, tên thuộc tính khớp với các từ dành riêng trong ECMA-Script 3 phải được đặt trong dấu ngoặc kép. Trong ECMAScript 5, dấu phẩy cuối cùng theo sau thuộc tính cuối cùng trong một đối tượng bằng chữ sẽ bị bỏ qua. Hầu hết việc triển khai ECMAScript 3 cũng bỏ qua dấu phẩy ở cuối, nhưng IE coi sự hiện diện của chúng là một lỗi.

    Một đối tượng bằng chữ là một biểu thức tạo và khởi tạo một đối tượng mới bất cứ khi nào biểu thức đó được đánh giá. Giá trị của mỗi thuộc tính được tính toán lại khi giá trị của hằng được đánh giá. Điều này có nghĩa là một nghĩa đen của một đối tượng có thể tạo ra nhiều đối tượng mới nếu nghĩa đen được đặt trong phần thân của một vòng lặp hoặc hàm sẽ được gọi lặp lại và các giá trị thuộc tính của các đối tượng này có thể khác nhau.

    Tạo đối tượng bằng toán tử mới

    Toán tử mới tạo và khởi tạo một đối tượng mới. Câu lệnh này phải được theo sau bởi tên hàm. Hàm được sử dụng theo cách này được gọi là hàm tạo và dùng để khởi tạo hàm mới được tạo của đối tượng này. JavaScript cơ bản bao gồm nhiều hàm tạo dựng sẵn để tạo các đối tượng ngôn ngữ cơ sở. Ví dụ:

    Var o = Đối tượng mới(); // Tạo một đối tượng trống mới: giống như () var a = new Array(); // Tạo một mảng trống: giống như var d = new Date(); // Tạo một đối tượng Date đại diện cho thời gian hiện tại var r = new RegExp("js"); // Tạo một đối tượng RegExp cho các thao tác khớp mẫu

    Ngoài các hàm tạo dựng sẵn này, bạn có thể xác định các hàm tạo của riêng mình để khởi tạo các đối tượng mới được tạo. Làm thế nào điều này được thực hiện được mô tả trong bài viết tiếp theo.

    Object.create()

    Tiêu chuẩn ECMAScript 5 xác định phương thức Object.create(), phương thức này tạo một đối tượng mới và sử dụng đối số đầu tiên của nó làm nguyên mẫu của đối tượng đó. Ngoài ra, Object.create() có thể lấy đối số tùy chọn thứ hai mô tả các thuộc tính của đối tượng mới.

    Object.create() là một hàm tĩnh, không phải là một phương thức được gọi trên một số đối tượng cụ thể. Để gọi hàm này, chỉ cần truyền cho nó đối tượng nguyên mẫu mong muốn:

    // obj kế thừa các thuộc tính x và y var obj = Object.create((x:1, y:2));

    Để tạo một đối tượng không có nguyên mẫu, bạn có thể truyền null, nhưng trong trường hợp này đối tượng mới được tạo sẽ không kế thừa bất kỳ thuộc tính hoặc phương pháp cơ bản, chẳng hạn như toString() (có nghĩa là đối tượng này không thể được sử dụng trong các biểu thức có toán tử +):

    // obj2 không kế thừa bất kỳ thuộc tính hoặc phương thức nào var obj2 = Object.create(null);

    Nếu chương trình của bạn cần tạo một đối tượng trống thông thường (được trả về bởi biểu thức chữ() hoặc một biểu thức Object() mới), hãy chuyển Object.prototype làm đối số đầu tiên:

    // obj3 giống như một đối tượng được tạo // sử dụng () hoặc new Object() var obj3 = Object.create(Object.prototype);

    Khả năng tạo các đối tượng mới với các nguyên mẫu tùy ý (nói cách khác: khả năng tạo ra “người thừa kế” từ bất kỳ đối tượng nào) là công cụ đắc lực, hiệu ứng của nó có thể được mô phỏng trong ECMAScript 3 bằng cách sử dụng hàm được trình bày trong ví dụ bên dưới:

    // kế thừa() trả về một đối tượng mới được tạo kế thừa các thuộc tính // của đối tượng nguyên mẫu p. Sử dụng hàm ECMAScript 5 Object.create() // nếu được xác định, nếu không thì sử dụng kỹ thuật cũ hơn. hàm kế thừa(p) ( if (p == null) Throw TypeError(); // p không thể rỗng nếu (Object.create) // Nếu Object.create() được xác định... return Object.create(p ) ; // sử dụng nó. var t = typeof p; // Nếu không, hãy tìm ra loại và kiểm tra nó nếu (t !== "object" && t !== "function") Throw TypeError(); một hàm tạo trống f.prototype = p; // Đặt thuộc tính nguyên mẫu của nó thành // một tham chiếu đến đối tượng p return new f(); // Sử dụng f() để tạo một // "người thừa kế" của đối tượng p. .

    Việc triển khai hàm kế thừa () sẽ có ý nghĩa hơn khi chúng ta làm quen với hàm tạo trong bài viết tiếp theo. Hiện tại, chỉ cần giả sử rằng nó trả về một đối tượng mới kế thừa các thuộc tính của đối tượng trong đối số. Lưu ý rằng kế thừa() không phải là sự thay thế hoàn toàn cho Object.create(): nó không cho phép bạn tạo các đối tượng mà không có nguyên mẫu và nó không lấy đối số thứ hai tùy chọn như Object.create().

    Lấy và thay đổi thuộc tính

    Bạn có thể lấy giá trị của một thuộc tính bằng cách sử dụng toán tử dấu chấm (.) và dấu ngoặc vuông (). Ở bên trái của toán tử phải có một biểu thức trả về một đối tượng. Khi sử dụng toán tử dấu chấm, cần có một mã định danh đơn giản ở bên phải khớp với tên thuộc tính. Khi sử dụng dấu ngoặc vuông, dấu ngoặc vuông phải bao gồm biểu thức trả về một chuỗi chứa tên của thuộc tính mong muốn:

    // Đối tượng đơn giản var user = ( login:"kot86", name:"Alexandr", age:26 ); var login = user.login; // Lấy thuộc tính "đăng nhập" của đối tượng người dùng var name = user.name; // Lấy thuộc tính "name" của đối tượng người dùng var age = user["age"]; // Lấy thuộc tính "age" của đối tượng người dùng

    Để tạo một thuộc tính mới hoặc thay đổi giá trị của một thuộc tính hiện có, các toán tử dấu chấm và dấu ngoặc vuông cũng được sử dụng, như trong các thao tác đọc giá trị thuộc tính, nhưng bản thân biểu thức được đặt ở bên trái của toán tử gán:

    Người dùng.age = 28; // Thay đổi giá trị của thuộc tính "age" user["login"] = "kot84"; // Thay đổi giá trị của thuộc tính "đăng nhập" user["họ"] = "Frolov"; // Tạo thuộc tính mới "họ"

    Trong ECMAScript 3, mã định danh theo sau dấu chấm không thể là từ dành riêng: bạn không thể viết lệnh gọi thuộc tính tới o.for hoặc o.class vì for là từ khóa và lớp là từ dành riêng để sử dụng trong tương lai.

    Nếu một đối tượng có các thuộc tính có tên khớp với các từ dành riêng, bạn phải sử dụng ký hiệu dấu ngoặc vuông để truy cập chúng: o["for"] và o["class"]. Tiêu chuẩn ECMAScript 5 nới lỏng yêu cầu này (như một số triển khai ECMAScript 3 đã thực hiện) và cho phép sử dụng các từ dành riêng sau toán tử dấu chấm.

    nguyên mẫu

    Mọi đối tượng trong JavaScript đều có đối tượng thứ hai (hoặc null, nhưng ít thường xuyên hơn) được liên kết với nó. Đối tượng thứ hai này được gọi là nguyên mẫu và đối tượng đầu tiên kế thừa các thuộc tính của nó từ nguyên mẫu.

    Tất cả các đối tượng được tạo bằng cách sử dụng hằng đối tượng đều có cùng một đối tượng nguyên mẫu, có thể được tham chiếu trong chương trình JavaScript dưới dạng Object.prototype .

    Các đối tượng được tạo bằng từ khóa new và lệnh gọi hàm tạo sẽ nhận giá trị thuộc tính nguyên mẫu của hàm hàm tạo làm nguyên mẫu của chúng. Do đó, một đối tượng được tạo bởi new Object() sẽ kế thừa các thuộc tính của Object.prototype như thể nó được tạo bằng cách sử dụng dấu ngoặc nhọn (). Tương tự, nguyên mẫu của một đối tượng được tạo bởi new Array() là Array.prototype và nguyên mẫu của một đối tượng được tạo bởi new Date() là Date.prototype.

    Object.prototype là một trong số ít đối tượng không có nguyên mẫu: nó không có thuộc tính kế thừa. Các đối tượng nguyên mẫu khác chỉ là những đối tượng bình thường có nguyên mẫu riêng.

    Tất cả các hàm tạo tích hợp (và hầu hết các hàm tạo tùy chỉnh) đều kế thừa nguyên mẫu Object.prototype. Ví dụ: Date.prototype kế thừa các thuộc tính từ Object.prototype, do đó, một đối tượng Date được tạo bởi new Date() sẽ kế thừa các thuộc tính từ cả Date.prototype và Object.prototype. Chuỗi các đối tượng nguyên mẫu được kết nối như vậy được gọi là chuỗi nguyên mẫu.

    Di sản

    Các đối tượng trong JavaScript có nhiều "thuộc tính riêng" và cũng có thể kế thừa nhiều thuộc tính từ đối tượng nguyên mẫu của chúng. Để hiểu điều này, bạn cần nghiên cứu kỹ cơ chế truy cập tài sản. Các ví dụ trong phần này sử dụng hàm kế thừa() được hiển thị ở trên để tạo các đối tượng có nguyên mẫu cụ thể.

    Giả sử chương trình truy cập thuộc tính x của đối tượng obj. Nếu obj không có thuộc tính riêng có tên đó, một nỗ lực sẽ được thực hiện để tra cứu thuộc tính x trong nguyên mẫu của obj. Nếu đối tượng nguyên mẫu không có thuộc tính riêng với tên đó, nhưng có nguyên mẫu riêng, thì một nỗ lực sẽ được thực hiện để tra cứu thuộc tính trong nguyên mẫu của nguyên mẫu. Điều này tiếp tục cho đến khi tìm thấy thuộc tính x hoặc một đối tượng không có nguyên mẫu. Như bạn có thể thấy, thuộc tính nguyên mẫu của một đối tượng tạo ra một chuỗi, hoặc danh sách liên kết các đối tượng mà từ đó các thuộc tính được kế thừa.

    Var obj = (); // obj kế thừa các phương thức của đối tượng Object.prototype obj.x = 1; // và có thuộc tính riêng x. var p = kế thừa(obj); // p kế thừa các thuộc tính của đối tượng obj và Object.prototype p.y = 2; // và có thuộc tính riêng y. var q = kế thừa(p); // q kế thừa các thuộc tính của đối tượng p, obj và Object.prototype q.z = 3; // và có thuộc tính riêng z. var s = q.toString(); // toString kế thừa từ Object.prototype var d = q.x + q.y // Kết quả 3: x và y kế thừa từ obj và p

    Bây giờ giả sử chương trình gán một giá trị nào đó cho thuộc tính x của obj. Nếu obj đã có thuộc tính riêng (không được kế thừa) có tên x, thì thao tác gán sẽ chỉ thay đổi giá trị của thuộc tính hiện có. Nếu không, một thuộc tính mới có tên x sẽ được tạo trong obj. Nếu obj thuộc tính được kế thừa trước đó x thì thuộc tính được kế thừa bây giờ sẽ bị ẩn bởi thuộc tính mới được tạo của chính nó có cùng tên.

    Hoạt động gán giá trị cho một thuộc tính sẽ kiểm tra sự hiện diện của thuộc tính đó trong chuỗi nguyên mẫu để đảm bảo rằng phép gán là hợp lệ. Ví dụ: nếu đối tượng obj kế thừa thuộc tính chỉ đọc x thì việc gán sẽ không xảy ra. Tuy nhiên, nếu phép gán hợp lệ, thuộc tính luôn được tạo hoặc thay đổi trong đối tượng ban đầu và không bao giờ có trong chuỗi nguyên mẫu. Thực tế là tính kế thừa hoạt động khi các thuộc tính được đọc chứ không phải khi các giá trị mới được ghi, là một tính năng chính của ngôn ngữ JavaScript vì nó cho phép các thuộc tính kế thừa được ghi đè có chọn lọc:

    Var vòng tròn đơn vị = ( r:1 ); // Đối tượng mà thuộc tính được kế thừa từ đó var c = kế thừa(unitcircle); // c kế thừa thuộc tính r c.x = 1; c.y = 1; // c định nghĩa hai thuộc tính của chính nó c.r = 2; // c ghi đè thuộc tính kế thừa console.log(unitcircle.r); // => 1: đối tượng nguyên mẫu không thay đổi

    Có một ngoại lệ đối với quy tắc này, khi thao tác gán thuộc tính không thành công hoặc dẫn đến một thuộc tính được tạo/sửa đổi trên đối tượng ban đầu. Nếu obj kế thừa thuộc tính x và thuộc tính đó được truy cập thông qua các trình truy cập, thì thay vì tạo thuộc tính x mới trên obj, một phương thức ghi giá trị mới sẽ được gọi. Tuy nhiên, lưu ý rằng phương thức ghi được gọi trên obj, không phải trên nguyên mẫu mà thuộc tính được xác định, vì vậy nếu phương thức ghi xác định bất kỳ thuộc tính nào, chúng sẽ được khởi tạo trên obj và chuỗi nguyên mẫu sẽ lại không thay đổi.

    Lỗi truy cập thuộc tính

    Các biểu thức truy cập thuộc tính không phải lúc nào cũng trả về hoặc thay đổi giá trị của thuộc tính. Phần này mô tả các tình huống khi thao tác đọc hoặc ghi thuộc tính không thành công.

    Nỗ lực truy cập vào một thuộc tính không tồn tại không được coi là lỗi. Nếu không tìm thấy thuộc tính x trong các thuộc tính riêng hoặc được kế thừa của obj, biểu thức truy cập thuộc tính obj.x sẽ trả về không xác định.

    Tuy nhiên, việc cố gắng truy cập vào thuộc tính của một đối tượng không tồn tại được coi là một lỗi. Các giá trị null và không xác định không có thuộc tính và các nỗ lực truy cập vào thuộc tính của các giá trị này được coi là lỗi:

    // Đối tượng đơn giản var user = ( login:"kot86", name:"Alexandr", age:26 ); var a = user.password; // không xác định: thuộc tính bị thiếu // Tạo ra ngoại lệ TypeError. // Giá trị không xác định không có thuộc tính độ dài var len = user.password.length;

    Nếu bạn không chắc chắn rằng user và user.password là các đối tượng (hoặc hoạt động giống như các đối tượng), bạn không nên sử dụng biểu thức user.password.length vì nó có thể tạo ra một ngoại lệ. Phần sau đây trình bày hai cách để bảo vệ chống lại loại ngoại lệ này:

    // Cách trực quan và đơn giản hơn var len = unfind; if (user) ( if (user.password) len = user.password.length; ) // Một giải pháp thay thế ngắn gọn hơn, dành riêng cho JavaScript // ​​để lấy độ dài của giá trị thuộc tính mật khẩu var len = user && user. mật khẩu && user.password.length ;

    Cố gắng đặt giá trị của thuộc tính thành các giá trị khác không phải lúc nào cũng thành công: một số thuộc tính ở chế độ chỉ đọc và không cho phép thay đổi giá trị của chúng. Ngoài ra, một số đối tượng không cho phép bạn thêm thuộc tính mới vào chúng. Tuy nhiên, điều thú vị nhất là những lỗi như vậy, theo quy luật, không dẫn đến một ngoại lệ nào được nêu ra:

    // Thuộc tính nguyên mẫu của hàm tạo dựng sẵn là Object.prototype = 0 chỉ đọc; // Phép gán sẽ không đưa ra ngoại lệ; // giá trị của Object.prototype sẽ không thay đổi

    Lỗ hổng JavaScript lịch sử này được sửa ở chế độ nghiêm ngặt, như được xác định bởi tiêu chuẩn ECMAScript 5. Tất cả các nỗ lực không thành công để thay đổi giá trị thuộc tính ở chế độ nghiêm ngặt đều dẫn đến ngoại lệ TypeError.

    Các quy tắc để xác định khi nào một nỗ lực thực hiện một thao tác gán sẽ thành công và khi nào nó sẽ thất bại rất đơn giản và dễ hiểu, nhưng khó diễn đạt một cách ngắn gọn. Việc cố gắng gán giá trị cho thuộc tính p của obj sẽ không thành công trong các trường hợp sau:

      Đối tượng obj có thuộc tính chỉ đọc p riêng của nó: bạn không thể thay đổi giá trị của thuộc tính chỉ đọc. (Tuy nhiên, lưu ý rằng phương thức definProperty() là một ngoại lệ cho phép bạn thay đổi giá trị của các thuộc tính tùy chỉnh chỉ đọc.)

      Đối tượng obj có thuộc tính kế thừa chỉ đọc p: các thuộc tính chỉ đọc được kế thừa không thể bị ghi đè bởi các thuộc tính có cùng tên của chính bạn.

      Đối tượng obj không có thuộc tính p riêng; obj không kế thừa thuộc tính p bằng các phương thức truy cập và thuộc tính mở rộng của obj là sai. Nếu thuộc tính p không có trong obj và không có phương thức ghi nào được xác định cho nó thì thao tác gán sẽ cố gắng thêm thuộc tính p vào obj. Nhưng vì obj không thể mở rộng được nên việc cố gắng thêm thuộc tính mới vào nó sẽ không thành công.

    Xóa thuộc tính

    Toán tử xóa sẽ loại bỏ một thuộc tính khỏi một đối tượng. Toán hạng duy nhất của nó phải là biểu thức truy cập thuộc tính. Điều này có vẻ đáng ngạc nhiên, nhưng toán tử xóa không ảnh hưởng đến giá trị của thuộc tính - nó hoạt động trên chính thuộc tính đó:

    // Đối tượng đơn giản var user = ( login:"kot86", name:"Alexandr", age:26 ); xóa user.login; // Bây giờ đối tượng người dùng không có thuộc tính đăng nhập delete user["name"]; // Bây giờ đối tượng người dùng không có thuộc tính tên

    Toán tử xóa chỉ xóa các thuộc tính của chính nó và không xóa các thuộc tính kế thừa. (Để xóa một thuộc tính được kế thừa, bạn phải xóa nó khỏi đối tượng nguyên mẫu mà nó được xác định. Thao tác này sẽ ảnh hưởng đến tất cả các đối tượng kế thừa nguyên mẫu đó.)

    Biểu thức xóa trả về true khi thuộc tính đã được xóa thành công hoặc khi thao tác xóa không làm thay đổi đối tượng (ví dụ: khi cố gắng xóa một thuộc tính không tồn tại). Biểu thức xóa cũng trả về true khi truyền một biểu thức không phải là biểu thức truy cập thuộc tính:

    Obj = (x:1); // obj có thuộc tính x riêng và kế thừa toString delete obj.x; //Xóa x và trả về true delete obj.x; // Không làm gì cả (x không tồn tại) và trả về true delete obj.toString; // Sẽ không làm gì cả (toString không phải là thuộc tính riêng của nó) và return true delete 1; // Vô nghĩa nhưng sẽ trả về true

    Toán tử xóa không xóa các thuộc tính, thuộc tính không thể cấu hình có thể cấu hình có giá trị sai. (Tuy nhiên, nó có thể loại bỏ các thuộc tính tùy chỉnh trên các đối tượng không thể mở rộng.) Các thuộc tính không thể cấu hình là các thuộc tính đối tượng tích hợp sẵn, cũng như các thuộc tính đối tượng chung được tạo bằng cách sử dụng các câu lệnh khai báo biến và hàm. Việc cố gắng xóa thuộc tính không thể định cấu hình ở chế độ nghiêm ngặt sẽ gây ra Lỗi Loại. Ở chế độ không nghiêm ngặt (và trong triển khai ECMAScript 3), toán tử xóa chỉ trả về false trong những trường hợp như vậy:

    Xóa Object.prototype; // Không thể xóa - thuộc tính không thể cấu hình var x = 1; // Khai báo biến toàn cục delete this.x; // Thuộc tính này không thể xóa được function f() () // Khai báo hàm toàn cục delete this.f; // Thuộc tính này cũng không thể xóa được

    Kiểm tra sự tồn tại của thuộc tính

    Các đối tượng trong JavaScript có thể được coi là tập hợp các thuộc tính và việc kiểm tra tư cách thành viên trong một tập hợp thường rất hữu ích - để kiểm tra xem một đối tượng có thuộc tính có tên nhất định hay không. Bạn có thể thực hiện kiểm tra như vậy bằng toán tử in, sử dụng các phương thức hasOwnProperty()propertyIsEnumerable() hoặc đơn giản bằng cách truy cập vào tài sản.

    Toán tử in yêu cầu nó phải có tên thuộc tính (dưới dạng chuỗi) làm toán hạng bên trái và một đối tượng làm toán hạng bên phải. Nó trả về true nếu đối tượng có thuộc tính riêng hoặc thuộc tính kế thừa có tên đó:

    Var obj = ( x:1 ) "x" trong obj; // true: obj có thuộc tính riêng "x" "y" trong obj; // false: obj không có thuộc tính "y" "toString" trong obj; // true: obj kế thừa thuộc tính toString

    Phương thức hasOwnProperty() của một đối tượng sẽ kiểm tra xem đối tượng đó có thuộc tính riêng của nó hay không với tên được chỉ định. Đối với các thuộc tính được kế thừa, nó trả về false:

    Var obj = ( x:1 ) obj.hasOwnProperty("x"); // true: obj có thuộc tính riêng "x" obj.hasOwnProperty("y"); // false: obj không có thuộc tính "y" obj.hasOwnProperty("toString"); // false: toString - thuộc tính kế thừa

    Phương thức propertyIsEnumerable() áp đặt hạn chế bổ sung so với hasOwnProperty(). Nó chỉ trả về true nếu thuộc tính được chỉ định là thuộc tính gốc có thuộc tính đếm được được đặt thành true. Thuộc tính của các đối tượng tích hợp không thể đếm được. Các thuộc tính được tạo bởi chương trình JavaScript thông thường có thể đếm được trừ khi một trong các phương thức ECMAScript 5 bên dưới được sử dụng để làm cho các thuộc tính không thể đếm được.

    Thông thường, thay vì toán tử in, chỉ cần sử dụng biểu thức truy cập thuộc tính đơn giản và sử dụng toán tử !== để kiểm tra sự bất đẳng thức với giá trị không xác định là đủ:

    Var obj = ( x:1 ) obj.x !== không xác định; // true: obj có thuộc tính "x" obj.y !== unknown; // false: obj không có thuộc tính "y" obj.toString !== unknown; // true: obj kế thừa thuộc tính toString

    Tuy nhiên, toán tử in phân biệt các tình huống không thể phân biệt được bằng cách sử dụng kỹ thuật dựa trên thuộc tính được trình bày ở trên. Toán tử in phân biệt sự vắng mặt của thuộc tính với thuộc tính có giá trị không xác định.

    Liệt kê các thuộc tính

    Thay vì kiểm tra các thuộc tính riêng lẻ, đôi khi bạn muốn lặp lại tất cả các thuộc tính hiện có hoặc lấy danh sách tất cả các thuộc tính của một đối tượng. Điều này thường được thực hiện bằng vòng lặp for/in, nhưng tiêu chuẩn ECMAScript 5 cung cấp hai lựa chọn thay thế thuận tiện.

    Câu lệnh vòng lặp for/in thực thi phần thân của vòng lặp cho mỗi thuộc tính có thể đếm được (của chính nó hoặc được kế thừa) đối tượng được chỉ định, gán tên thuộc tính cho một biến vòng lặp. Các phương thức tích hợp được kế thừa bởi các đối tượng là không thể đếm được và các thuộc tính được chương trình của bạn thêm vào đối tượng là có thể đếm được (trừ khi bạn sử dụng các hàm được mô tả bên dưới để làm cho các thuộc tính không thể đếm được). Ví dụ:

    // Một đối tượng đơn giản với ba thuộc tính có thể đếm được var user = ( login:"kot86", name:"Alexandr", age:26 ); user.propertyIsEnumerable("toString"); // false, toString - phương thức tích hợp cho (n trong người dùng) console.log(n);

    Một số thư viện thêm các phương thức mới (hoặc các thuộc tính khác) vào đối tượng Object.prototype để chúng có thể được kế thừa và cung cấp cho tất cả các đối tượng. Tuy nhiên, cho đến khi có tiêu chuẩn ECMAScript 5, không có cách nào làm cho các phương thức bổ sung này không thể đếm được, vì vậy cuối cùng chúng được liệt kê trong vòng lặp for/in. Để giải quyết vấn đề này, bạn có thể cần lọc các thuộc tính được vòng lặp for/in trả về. Dưới đây là hai ví dụ về việc triển khai tính năng lọc như vậy:

    For (n in user) ( if (!user.hasOwnProperty(n)) continue; console.log(n); ) for (n in user) ( if (typeof user[n] === "function") continue; console.log(n);

    Ngoài vòng lặp for/in, tiêu chuẩn ECMAScript 5 còn xác định hai hàm liệt kê tên thuộc tính. Cái đầu tiên trong số này, Object.keys(), trả về một mảng tên của các thuộc tính có thể đếm được của chính đối tượng.

    Hàm ECMAScript 5 thứ hai thực hiện liệt kê thuộc tính là Object.getOwnPropertyNames() . Nó hoạt động giống như hàm Object.keys(), nhưng trả về tên của tất cả thuộc tính riêng của đối tượng được chỉ định, không chỉ những thuộc tính có thể đếm được. Việc triển khai ECMAScript 3 không có khả năng triển khai chức năng như vậy vì ECMAScript 3 không cung cấp khả năng thu được các thuộc tính không thể đếm được của một đối tượng.

    Các phương thức đọc và ghi thuộc tính

    Ở trên đã nói rằng thuộc tính đối tượng có tên, giá trị và tập hợp các thuộc tính. Trong ECMAScript 5, một giá trị có thể được thay thế bằng một hoặc hai phương thức, được gọi là phương thức getter và setter. Các thuộc tính mà các phương thức đọc và ghi được xác định đôi khi được gọi là thuộc tính với các phương thức truy cậpđể phân biệt chúng với các thuộc tính dữ liệu đại diện cho một giá trị đơn giản.

    Khi một chương trình cố gắng lấy giá trị của một thuộc tính bằng các phương thức truy cập, trình thông dịch sẽ gọi phương thức đọc (không có đối số). Giá trị được phương thức này trả về sẽ trở thành giá trị của biểu thức truy cập thuộc tính. Khi một chương trình cố gắng ghi một giá trị vào một thuộc tính, trình thông dịch sẽ gọi phương thức ghi, chuyển giá trị đó sang bên phải toán tử gán. Phương pháp này chịu trách nhiệm "thiết lập" giá trị của thuộc tính. Giá trị được trả về bởi phương thức ghi sẽ bị bỏ qua.

    Không giống như thuộc tính dữ liệu, thuộc tính truy cập không có thuộc tính có thể ghi. Nếu một thuộc tính có cả phương thức đọc và ghi thì đó là đọc/ghi. Nếu một thuộc tính chỉ có một phương thức đọc thì nó ở dạng chỉ đọc. Và nếu một thuộc tính chỉ có một phương thức ghi thì nó chỉ ở chế độ ghi (điều này là không thể đối với các thuộc tính dữ liệu) và các nỗ lực đọc giá trị của thuộc tính đó sẽ luôn trả về không xác định.

    Cách đơn giản nhất để xác định một thuộc tính bằng các phương thức truy cập là sử dụng cú pháp định nghĩa đối tượng mở rộng theo nghĩa đen:

    Var obj = ( // Một thuộc tính thông thường có dữ liệu data_prop: value, // Một thuộc tính với các phương thức truy cập được định nghĩa là một cặp hàm get accessor_prop() ( /* function body */ ), set accessor_prop(value) ( ​​​/* nội dung hàm */ ) );

    Các thuộc tính với các phương thức truy cập được định nghĩa là một hoặc hai hàm có tên giống với tên thuộc tính và có từ khóa hàm được thay thế bằng get và/hoặc set.

    Lưu ý rằng bạn không bắt buộc phải sử dụng dấu hai chấm để phân tách tên thuộc tính khỏi hàm kiểm soát quyền truy cập vào thuộc tính, nhưng bạn vẫn phải sử dụng dấu phẩy sau thân hàm để phân tách phương thức khỏi các phương thức hoặc thuộc tính dữ liệu khác.

    Ví dụ, hãy xem xét đối tượng sau đây, biểu thị tọa độ Descartes của một điểm trên mặt phẳng. Nó có các thuộc tính dữ liệu thông thường để biểu thị tọa độ X và Y, cũng như các thuộc tính với các phương thức truy cập để có được tọa độ cực tương đương của một điểm:

    Var p = ( // x và y là thuộc tính dữ liệu thông thường, đọc/ghi x: 1.0, y: 1.0, // r là thuộc tính đọc/ghi với hai phương thức truy cập. // Đừng quên thêm dấu phẩy sau các phương thức truy cập get r() ( return Math.sqrt(this.x*this.x + this.y*this.y); ), set r(newvalue) ( ​​​​var oldvalue = Math.sqrt(this.x* this.x + this.y*this.y); tỷ lệ var = giá trị mới/giá trị cũ; phương pháp duy nhấtđọc get theta() ( return Math.atan2(this.y, this.x); ) );

    Lưu ý việc sử dụng từ khóa this trong các phương thức đọc và ghi ở trên. Trình thông dịch sẽ gọi các hàm này là các phương thức của đối tượng mà chúng được định nghĩa, tức là. trong phần thân của hàm, this sẽ đề cập đến đối tượng điểm. Điều này cho phép phương thức đọc thuộc tính r tham chiếu đến các thuộc tính x và y, như this.x và this.y.

    Các thuộc tính với các phương thức truy cập được kế thừa giống như các thuộc tính dữ liệu thông thường, vì vậy đối tượng p được xác định ở trên có thể được sử dụng làm nguyên mẫu cho các đối tượng điểm khác. Các đối tượng mới có thể xác định các thuộc tính x và y của riêng chúng và chúng sẽ kế thừa các thuộc tính r và theta.

    Thuộc tính đối tượng

    Tất cả các đối tượng đều có các thuộc tính nguyên mẫu, lớp và có thể mở rộng. Tất cả các thuộc tính này được mô tả trong các phần phụ bên dưới.

    thuộc tính nguyên mẫu

    Thuộc tính nguyên mẫu của một đối tượng chỉ định đối tượng mà các thuộc tính được kế thừa. Điều quan trọng là phải hiểu rằng khi một tham chiếu nguyên mẫu xuất hiện trong mã chương trình, nó biểu thị một thuộc tính thông thường của một đối tượng chứ không phải thuộc tính nguyên mẫu.

    Thuộc tính nguyên mẫu được đặt khi đối tượng được tạo. Đối với các đối tượng được tạo bằng chữ, nguyên mẫu là Object.prototype. Nguyên mẫu của một đối tượng được tạo bằng toán tử mới là giá trị thuộc tính nguyên mẫu của hàm tạo. Và nguyên mẫu của đối tượng được tạo bằng Object.create() sẽ trở thành đối số đầu tiên của hàm này (có thể là null).

    Tiêu chuẩn ECMAScript 5 cung cấp khả năng xác định nguyên mẫu của bất kỳ đối tượng nào bằng cách chuyển nó tới phương thức Object.getPrototypeOf(). ECMAScript 3 không có chức năng tương đương, nhưng bạn thường có thể xác định nguyên mẫu của obj bằng cách sử dụng biểu thức obj.constructor.prototype.

    Các đối tượng được tạo bằng toán tử new thường kế thừa thuộc tính hàm tạo, tham chiếu đến hàm tạo được sử dụng để tạo đối tượng. Và như đã đề cập ở trên, các hàm tạo có một thuộc tính nguyên mẫu, xác định nguyên mẫu của các đối tượng được tạo bằng hàm tạo này.

    Lưu ý rằng các đối tượng được tạo bằng cách sử dụng hằng đối tượng hoặc Object.create() sẽ nhận thuộc tính hàm tạo tham chiếu đến hàm tạo Object(). Do đó, constructor.prototype đề cập đến nguyên mẫu thực sự cho các hằng đối tượng, nhưng điều này thường không xảy ra đối với các đối tượng được tạo bằng cách gọi Object.create().

    Để xác định xem một đối tượng có phải là nguyên mẫu (hoặc một liên kết trong chuỗi nguyên mẫu) của đối tượng khác hay không, hãy sử dụng phương thức isPrototypeOf(). Để tìm hiểu xem p có phải là nguyên mẫu của obj hay không, bạn cần viết biểu thức p.isPrototypeOf(obj). Ví dụ:

    Var p = (x:1); // Định nghĩa một đối tượng nguyên mẫu. var obj = Object.create(p); // Tạo một đối tượng với nguyên mẫu này. p.isPrototypeOf(obj); // => true: obj kế thừa p Object.prototype.isPrototypeOf(p); // => true: p kế thừa Object.prototype

    thuộc tính lớp

    Thuộc tính lớp của đối tượng là một chuỗi chứa thông tin về loại đối tượng. Cả ECMAScript 3 và ECMAScript 5 đều không cung cấp khả năng thay đổi thuộc tính này và chỉ cung cấp các cách gián tiếp để xác định giá trị của nó. Theo mặc định, phương thức toString() (được kế thừa từ Object.prototype) trả về một chuỗi như:

    Do đó, để xác định lớp của một đối tượng, bạn có thể thử gọi phương thức toString() của đối tượng này và trích xuất chuỗi con từ ký tự thứ tám đến ký tự áp chót từ kết quả. Phần khó khăn là nhiều phương thức kế thừa từ các cách triển khai toString() khác, hữu ích hơn và để gọi đúng phiên bản toString(), bạn cần thực hiện lệnh gọi gián tiếp bằng phương thức Function.call().

    Ví dụ dưới đây định nghĩa một hàm trả về lớp của bất kỳ đối tượng nào được truyền cho nó:

    // Tên của lớp đối tượng function classof(obj) ( if (obj === null) return "Null"; if (obj === unexpected) return "Unknown"; return Object.prototype.toString.call(obj) .slice (8,-1);

    Hàm classof() này có thể được truyền bất kỳ giá trị nào được cho phép trong JavaScript. Các số, chuỗi và boolean hoạt động giống như các đối tượng khi toString() được gọi trên chúng, nhưng các giá trị null và không xác định được xử lý khác nhau.

    thuộc tính mở rộng

    Thuộc tính mở rộng của một đối tượng xác định liệu các thuộc tính mới có thể được thêm vào đối tượng hay không. Trong ECMAScript 3, tất cả các đối tượng tích hợp và do người dùng xác định đều có thể mở rộng hoàn toàn và khả năng mở rộng của các đối tượng thời gian chạy là tùy theo cách triển khai. Trong ECMAScript 5, tất cả các đối tượng tích hợp và do người dùng xác định đều có thể mở rộng trừ khi chúng được chuyển đổi thành đối tượng không thể mở rộng và khả năng mở rộng của các đối tượng thời gian chạy vẫn tùy thuộc vào việc triển khai cụ thể.

    Tiêu chuẩn ECMAScript 5 xác định các hàm để nhận và thay đổi thuộc tính mở rộng của một đối tượng. Để xác định xem một đối tượng có thể được mở rộng hay không, nó phải được chuyển đến phương thức Object.isExtensible(). Để làm cho một đối tượng không thể mở rộng, bạn cần chuyển nó sang phương thức Object.preventExtensions(). Lưu ý rằng một khi một đối tượng được đặt ở trạng thái không thể mở rộng thì nó không thể mở rộng được nữa. Cũng lưu ý rằng lệnh gọi PreventExtensions() chỉ ảnh hưởng đến khả năng mở rộng của chính đối tượng đó. Nếu các thuộc tính mới được thêm vào nguyên mẫu của một đối tượng không thể mở rộng, đối tượng không thể mở rộng sẽ kế thừa các thuộc tính mới đó.

    Mục đích của thuộc tính mở rộng là giúp có thể “cố định” các đối tượng ở một trạng thái nhất định, cấm thay đổi. Thuộc tính mở rộng của các đối tượng thường được sử dụng cùng với các thuộc tính thuộc tính có thể cấu hình và ghi được, vì vậy ECMAScript 5 xác định các hàm giúp dễ dàng thiết lập các thuộc tính này cùng một lúc.

    Phương thức Object.seal() hoạt động tương tự như phương thức Object.preventExtensions(), nhưng nó không chỉ làm cho đối tượng không thể mở rộng mà còn khiến tất cả các thuộc tính của đối tượng đó không thể định cấu hình được. Nghĩa là, các thuộc tính mới không thể được thêm vào đối tượng và các thuộc tính hiện có không thể bị xóa hoặc định cấu hình. Tuy nhiên, các thuộc tính có thể ghi hiện tại vẫn có thể được thay đổi.

    Khi Object.seal() được gọi, đối tượng không thể được đưa về trạng thái trước đó. Để xác định xem phương thức Object.seal() đã được gọi trên một đối tượng hay chưa, bạn có thể gọi phương thức Object.isSealed().

    Phương thức Object.freeze() cho phép các đối tượng được đóng băng chặt chẽ hơn nữa. Ngoài việc làm cho đối tượng không thể mở rộng và các thuộc tính của nó không thể định cấu hình, nó còn làm cho tất cả các thuộc tính dữ liệu gốc ở chế độ chỉ đọc. (Điều này không áp dụng cho các thuộc tính đối tượng với các phương thức truy cập có phương thức ghi; những phương thức đó sẽ vẫn được gọi bằng câu lệnh gán.) Để xác định xem phương thức Object.freeze() của đối tượng đã được gọi hay chưa, bạn có thể gọi Object.isFrozen( ) phương pháp.

    Điều quan trọng là phải hiểu rằng Object.seal() và Object.freeze() chỉ ảnh hưởng đến đối tượng được truyền cho chúng: chúng không ảnh hưởng đến nguyên mẫu của đối tượng đó. Nếu chương trình của bạn cần chuyển giao hoàn toàn một đối tượng, có thể bạn cũng sẽ cần phải nắm bắt các đối tượng trong chuỗi nguyên mẫu.

    Tuần tự hóa đối tượng

    Tuần tự hóa đối tượng là quá trình chuyển đổi các đối tượng thành dạng biểu diễn chuỗi, sau này có thể được sử dụng để khôi phục chúng. Để tuần tự hóa và khôi phục các đối tượng JavaScript, tiêu chuẩn ECMAScript 5 cung cấp các hàm dựng sẵn JSON.stringify() và JSON.parse() . Các hàm này sử dụng định dạng trao đổi dữ liệu JSON. Tên JSON xuất phát từ "Ký hiệu đối tượng JavaScript" (một dạng ký hiệu đối tượng JavaScript) và cú pháp của ký hiệu này tương tự như cú pháp của đối tượng và mảng bằng chữ trong JavaScript:

    Var obj = (x:1, y:(z:)); // Xác định đối tượng test var s = JSON.stringify(obj); // s == "("x":1,"y":("z":))" var p = JSON.parse(s); // p - bản sao của đối tượng obj

    Cú pháp định dạng JSON chỉ là một tập hợp con của cú pháp JavaScript và không thể được sử dụng để biểu diễn tất cả các giá trị có thể được phép trong JavaScript. Được hỗ trợ và có thể được tuần tự hóa và khôi phục: đối tượng, mảng, chuỗi, cuối cùng giá trị số, đúng, sai và không có giá trị. Các giá trị NaN, Infinity và -Infinity được tuần tự hóa thành null. Các đối tượng Date được tuần tự hóa thành các chuỗi ngày ISO, nhưng JSON.parse() để chúng ở dạng biểu diễn chuỗi và không khôi phục các đối tượng Date ban đầu.

    Các đối tượng hàm, RegExp và Error cũng như giá trị không xác định không thể được tuần tự hóa hoặc khôi phục. Hàm JSON.stringify() chỉ tuần tự hóa các thuộc tính gốc có thể đếm được của một đối tượng. Nếu giá trị của một thuộc tính không thể được tuần tự hóa thì thuộc tính đó sẽ bị loại khỏi biểu diễn chuỗi. Cả JSON.stringify() và JSON.parse() đều lấy một đối số thứ hai tùy chọn có thể được sử dụng để tùy chỉnh quá trình tuần tự hóa và/hoặc khôi phục, ví dụ: bằng cách xác định danh sách các thuộc tính sẽ được tuần tự hóa hoặc một hàm để chuyển đổi các giá trị trong quá trình tuần tự hóa.

    Lượt truy cập vào tài nguyên web là một URI cụ thể trên thanh địa chỉ của trình duyệt. Người truy cập cung cấp địa chỉ của trang và được trình duyệt phân tích thành các phần tử của cây DOM - Tài liệu Mô hình đối tượng. Bất kỳ liên kết nào trên trang này sẽ yêu cầu trình duyệt phân tích một trang khác và xây dựng một cây đối tượng khác.

    Trình duyệt cho phép khách truy cập quay lại hoặc chuyển tiếp qua một chuỗi các trang đã được xem trong phiên hiện tại.

    Thực chất, hành động của người dùng là sự chuyển động giữa các hệ thống đối tượng được hình thành trong quá trình truy cập trang. Mỗi trang là một cây DOM riêng và ngoài ra, các đối tượng JavaScript là đối tượng của cú pháp của chính ngôn ngữ và mô tả của người dùng.

    DOM: tải, cập nhật và thay đổi

    Có ba tùy chọn chính hình thành các đối tượng của trang tài nguyên web, cả ở cấp độ DOM và chính ngôn ngữ JavaScript, thực hiện các cấu trúc tạo biến và dựa trên các mô tả do nhà phát triển đưa ra:

    • đang tải - khách truy cập đã đến trang của trang web;
    • cập nhật - khách truy cập (nút trình duyệt hoặc Ctrl-F5);
    • thay đổi một thành phần trang, ví dụ (AJAX, tập lệnh, sự kiện, ...).

    Cả ba quy trình đều khác nhau về cơ bản, nhưng việc phân biệt các đặc điểm của hai quy trình đầu tiên là đặc biệt quan trọng. Rất khó để ngăn khách truy cập làm mới trang - đây là một thói quen “xấu” không thể bỏ được của khách truy cập mà nhà phát triển nên ghi nhớ.

    Điều hướng trên trang và hơn thế nữa chỉ nên dựa vào chức năng của chính trang đó chứ không phải trong lịch sử trình duyệt và chức năng của các nút trên đó. Nhiều trang tuyên bố điều này yêu cầu quan trọng, nhưng theo truyền thống, du khách vi phạm điều đó.

    Thay đổi trang mà không tải lại ở cấp độ phần tử riêng lẻ (ví dụ: AJAX) là một giải pháp phổ biến cho các trang động. Theo quy định, điều này được sử dụng để điều hướng qua các thành phần trang, thay đổi đối tượng của trang và quản lý cuộc đối thoại với khách truy cập.

    Các đối tượng JavaScript cơ bản

    JavaScript dựa trên đối tượng. Hầu như tất cả các biến ngôn ngữ đều là đối tượng. Nhà phát triển có thể xây dựng mô tả riêng các đối tượng sử dụng nhiều tùy chọn cú pháp khác nhau.

    Bất kỳ thứ gì không phải là "chuỗi", "số", đúng, sai, null hoặc không xác định đều là một đối tượng. Trong khuôn khổ cú pháp ngôn ngữ, điều này có thể bị bỏ qua, nghĩa là các đối tượng chỉ là các phần tử DOM và của riêng chúng. Mô tả JavaScript Cấu trúc cơ bản của ngôn ngữ trong hầu hết các trường hợp không có ý nghĩa thực tiễn đáng kể đối với nhà phát triển.

    Ví dụ: các hàm toán học được biểu diễn bằng một đối tượng Math. Điều này thuận tiện trong khuôn khổ khái niệm ngôn ngữ, nhưng đối với nhà phát triển, nó chỉ đơn giản là một cú pháp thuận tiện để sử dụng kho phép toán cần thiết.

    Điều quan trọng là phải làm việc chính xác với DOM và mô tả chính xác các đối tượng của riêng bạn. Cú pháp của các hàm và biểu thức của đối tượng JavaScript để sử dụng chúng là một dạng ghi lại logic của thuật toán được yêu cầu.

    Chuỗi, mảng và đối tượng

    Tất cả các đối tượng JavaScript đều dựa trên quy tắc: "property" = "value" và khái niệm về mảng kết hợp. Chớm ban đầu trường hợp đơn giảnĐối tượng JavaScript là tập hợp các cặp thuộc tính = giá trị. Tuy nhiên, “giá trị” không phải lúc nào cũng là số và thuộc tính không phải lúc nào cũng được viết mà không có dấu ngoặc kép.

    Bạn không nên lạm dụng việc đặt tên thuộc tính. Thật lý tưởng khi tên thuộc tính chỉ chứa các ký tự Latinh, đáp ứng các yêu cầu đặt tên biến và không phải là các từ khóa (bao gồm cả dành riêng) của ngôn ngữ.

    Không cần phải có thứ tự các thuộc tính, nhưng khi tạo hoặc khởi tạo một mảng kết hợp, việc biết các phần tử của nó được sắp xếp như thế nào là hoàn toàn có thể chấp nhận được. Không nên sử dụng trường hợp này, nhưng có thể ghi nhớ nó.

    Khởi tạo một mảng thuộc tính có nghĩa là đồng thời:

    • tạo một mảng;
    • việc tạo đối tượng.

    Trong ngữ cảnh ứng dụng cụ thể, bạn có thể coi đối tượng JavaScript là một mảng kết hợp và ở một vị trí khác trong thuật toán là một đối tượng, gán các phương thức cần thiết cho nó, thay đổi giá trị của các phần tử của nó.

    Vì tên thuộc tính và giá trị của chúng phải được chỉ định ở định dạng chuỗi khi được tạo hoặc sửa đổi nên nên sử dụng ký hiệu chuỗi và dấu ngoặc kép.

    Truy cập thuộc tính đối tượng

    Bạn có thể lấy và thay đổi giá trị thuộc tính của đối tượng bằng cách sử dụng cấu trúc Object.keys: JavaScript tạo ra một mảng gồm tất cả các thuộc tính của đối tượng. Khi các đối tượng được tạo động, cấu trúc này rất thuận tiện vì nó tự động tạo ra một danh sách tất cả các thuộc tính có trong đối tượng.

    TRONG trong ví dụ này Hai mảng được mô tả khác nhau. Trong ứng dụng, cả hai mảng đều tương đương nhau vì chúng chứa các thuộc tính có cùng tên và giá trị của chúng. Vòng lặp lặp qua tất cả các thuộc tính của mảng thứ hai và tạo ra một chuỗi gồm tất cả các giá trị.

    Hiệu ứng tương tự có thể đạt được bằng ký hiệu dấu chấm hoặc dấu ngoặc:

    • x1_Obj.NameLast;
    • x1_Obj ["NameFirst" ].

    Cả hai cách xây dựng đều có giá trị và cho kết quả như ý. Trong ví dụ trên, khi chỉ định một mảng thông qua dấu ngoặc nhọn "()", có thể xảy ra lỗi ở dạng ký hiệu "," ở cuối bảng liệt kê (được đánh dấu trong ví dụ bằng vòng tròn màu đỏ). Các trình duyệt thường bỏ qua ký tự phụ trong bảng liệt kê, nhưng tốt hơn hết là không nên làm điều này.

    Loại bỏ thuộc tính đối tượng

    Vì một đối tượng là một mảng kết hợp nên thao tác xóa đối tượng JavaScript được thực hiện ở cấp độ của đối tượng hiện tại (khi kế thừa - điều này quan trọng) và được xem xét trên tập hợp các thuộc tính của đối tượng đó.

    Trong bối cảnh của ví dụ trên, bạn có thể sử dụng các cấu trúc sau:

    • xóa x1_Obj .NameLast ;
    • xóa x2_Obj ["NameFirst"];

    Cấu trúc đầu tiên loại bỏ phần tử thứ hai của đối tượng thứ nhất, cấu trúc thứ hai loại bỏ phần tử đầu tiên của đối tượng thứ hai. Toán tử xóa không hoạt động trên các thuộc tính nguyên mẫu và trả về false nếu thuộc tính không thể xóa được.

    Thuộc tính và phương thức của đối tượng

    Cú pháp của các thuộc tính và hàm (phương thức) đối tượng JavaScript tương tự như các quy tắc chung về cú pháp và ngữ nghĩa của ngôn ngữ. Trong thực tế, điều ngược lại là đúng.

    Các thuộc tính và phương thức của một đối tượng là một biến thể của việc mô tả thông tin và các hành động được phép thực hiện với nó thông qua mô hình JavaScript hướng đối tượng.

    Ví dụ này mô tả một đối tượng x3_Obj chỉ có hai thuộc tính: item và pos. Sau đó, phương thức hello() đã được thêm vào dưới dạng hàm. Kết quả là, các giá trị đối tượng JavaScript sẽ diễn giải mô tả này trong ngữ cảnh của các giá trị thuộc tính như được hiển thị trong cửa sổ kết quả, nghĩa là nó sẽ đặt phần thân hàm (1) làm giá trị.

    Khi gọi trực tiếp thuộc tính Hello(), nó được hiểu là một phương thức (hàm) và kết quả (2) là việc thực thi mã của phương thức này.

    Từ khóa this trong một đối tượng

    Để điều hướng không gian thuộc tính của một đối tượng, nhà phát triển có thể sử dụng từ khóa this và tham chiếu đến các thuộc tính mà nó mô tả để lấy hoặc thay đổi giá trị của chúng.

    Đây chỉ là bước khởi đầu của việc mô tả một đối tượng chỉ có phần thân hàm tạo. Ví dụ này mô tả một đối tượng để làm việc với cookie. Đối tượng được khởi tạo khi trang được tải bởi cấu trúc sau:

    • var oCookie = scCookies mới(cOwnerCode);
    • oCookie.Init();

    Trong ví dụ này, cOwnerCode là mã khách truy cập duy nhất. Nếu không có thì mã mới sẽ được tạo trong hàm tạo của đối tượng oCookie. Việc nhà phát triển đối tượng này có ý nghĩa gì khi ủy quyền cho khách truy cập không quan trọng, điều quan trọng là từ khóa này được sử dụng ở đây như thế nào để mô tả các phương thức của đối tượng và cách chúng được gọi từ các phương thức khác của đối tượng:

    • cái này .GetCookie = function (cName) ( ... );
    • cái này .SetCookie = function(cName,cValue)(... ).

    Phần này mô tả các phương thức của đối tượng để đọc cookie theo tên của nó và ghi giá trị của cookie bằng một tên cụ thể.

    • cái này .GetCookie("cOwner");
    • cái này .SetCookie ("cOwner", cowner);

    Đây là cách chúng được sử dụng, nếu do kết quả của cấu trúc đầu tiên mà giá trị không được biểu thị thì cấu trúc thứ hai sẽ thiết lập giá trị đó.

    Một ví dụ về đối tượng làm việc với cookie

    Bạn có thể thảo luận về Đối tượng và mô hình của cách tiếp cận ngôn ngữ hướng đối tượng chạy trong môi trường trình duyệt. Điều đó thật thú vị, nhưng trên thực tế, nó đòi hỏi phải thực hành chứ không phải lý thuyết. Phục vụ DOM của một trang, cung cấp các công cụ để thao tác đối tượng và điều hướng qua các hệ thống đối tượng. là một điểm mạnh của JavaScript.

    Trong thực hành hướng đối tượng, một điều khác rất quan trọng. Làm việc với cookie trên hầu hết các tài nguyên web là điều tất yếu. Thực hiện điều này ở định dạng đối tượng là một ý tưởng tuyệt vời. Trong ngữ cảnh này, quá trình khởi tạo đối tượng xảy ra tại thời điểm trang được mở: trang được tải = đối tượng cookie tồn tại và mọi thứ đã được đọc, còn những gì không có ở đó sẽ được tạo.

    Trong khi làm việc với trang, khách truy cập thực hiện một số hành động nhất định và trình duyệt phải thay đổi hoặc tạo cookie. Có hai phương thức đối tượng (được gắn nhãn ở trên) thực hiện việc này.

    Trên thực tế, đối tượng cookie xuất hiện ngay sau khi trình duyệt xây dựng DOM và thêm chức năng mới vào hệ thống đối tượng JavaScript: đọc và tạo (sửa đổi) cookie.

    Ví dụ đơn giản này được coi là một thủ tục để tạo các đối tượng thực có các thuộc tính và chức năng (phương thức) riêng của chúng. Mỗi đối tượng thực hiện công việc riêng của mình và không tham gia vào thuật toán chung, không thay đổi dữ liệu của các đối tượng khác hoặc không gian tên được chia sẻ.

    Với cách tiếp cận này, nhà phát triển đảm bảo tạo ra một hệ thống các đối tượng duy nhất đủ để mô tả và phục vụ vấn đề đang được giải quyết.

    Sự kiện trang và đối tượng

    Một yếu tố quan trọng trong hoạt động của DOM và JavaScript: sự kiện đối tượng "s - cho phép bạn lấy thông tin về một sự kiện trong trình xử lý của nó. Hầu hết mọi thành phần trang đều có thể được chỉ định trình xử lý riêng cho một hoặc nhiều sự kiện.

    Trên thực tế, nhà phát triển JavaScript không tạo ra một “đoạn” mã lớn mà tạo ra nhiều mô tả về chức năng, đối tượng, cấu trúc dữ liệu và gán trình xử lý sự kiện cho các thành phần trang cụ thể.

    Sự kiện đối tượng là thông tin về sự kiện khiến trình xử lý và khả năng của trình xử lý này thực hiện phản hồi đầy đủ cho sự kiện này. Mỗi sự kiện khác nhau không chỉ ở tên và nơi xảy ra mà còn ở nhiều thông số khác.

    Đặc biệt, các sự kiện bàn phím là một tập hợp các tham số, các sự kiện chuột là một phạm vi dữ liệu hoàn toàn khác và phản hồi của máy chủ thông qua AJAX hoàn toàn do chính nhà phát triển lên kế hoạch.

    Trong mỗi trường hợp cụ thể, hình ảnh về các sự kiện có thể xảy ra trên trang sẽ được chuyển đổi thành một loạt các trình xử lý được kích hoạt; bên ngoài các tùy chọn được cung cấp để xử lý một tập hợp sự kiện cụ thể, trang sẽ không thực hiện bất kỳ hành động nào.

    Tạo và vận hành các đối tượng

    Trình duyệt “chuyển đổi” URI, địa chỉ của tài nguyên web do khách truy cập chỉ định, thành cây DOM - hệ thống các đối tượng của trang của tài nguyên web này. Khi khách truy cập theo các liên kết trên một trang, trình duyệt sẽ chuyển đến các cây tương ứng của các trang khác.

    Tình huống này cho phép nhà phát triển xây dựng hệ thống đối tượng của mình làm nền tảng cho tài nguyên web đáp ứng đầy đủ hành vi của khách truy cập. Ví dụ: nếu chúng tôi tách biệt chức năng chung:

    • làm việc với cookie;
    • nhận/truyền dữ liệu (AJAX);
    • chú giải công cụ;
    • tin nhắn nội bộ (trò chuyện trên trang web);
    • các nhiệm vụ khác;

    sau đó, sau khi được tạo, các hệ thống đối tượng có thể được sử dụng khi phát triển các trang web khác. Đây là một lợi thế đáng kể cách tiếp cận đối tượng trước khi sử dụng JavaScript thông thường làm ngôn ngữ trình duyệt để đảm bảo hoạt động của trang và phản hồi các sự kiện.

    Đối tượng là các thành phần hoàn chỉnh có thể được định dạng như tập tin riêng biệt và sử dụng trong tương lai. Một tính năng đặc trưng của phương pháp này là khả năng phản hồi, khi một đối tượng được cập nhật, cải tiến có thể được sử dụng trong quá trình phát triển trước đó, tự động cập nhật chức năng của nó mà không cần sửa đổi trang web.

    Nhiệm vụ :

    1. Có ba vật thể (ba chiếc xe): first_Car, Second_Car và Third_Car.

    2. Mỗi đối tượng (ô tô) có một tập hợp các thuộc tính và các giá trị tương ứng của chúng (đặc điểm xe).

    3. Xét một trong các đối tượng:

    var first_Car = (
    tạo: "VAZ", /* nhà sản xuất */
    mô hình: 2106 , /* mô hình */
    năm: 1980 , /*năm sản xuất */
    màu: "màu be", /* màu */
    hành khách: 5 , /* số lượng hành khách */
    có thể chuyển đổi: sai, /* đỉnh có thể chuyển đổi */
    số dặm: 80000 /* số dặm */
    }

    Các thuộc tính tạo và màu có giá trị chuỗi;

    Các thuộc tính model , năm , hành khách và quãng đường là các giá trị số;

    Thuộc tính chuyển đổi có giá trị boolean.

    Bạn cần phải làm như sau:

    Viết hàm kiểm tra ô tô sử dụng hai tham số (năm sản xuất và số km đã đi) và trả về giá trị boolean đúng hoặc sai.

    Chi tiết:

    1. Hàm có một tham số car , nhận một trong 3 đối tượng. Ví dụ: chiếc xe được thảo luận ở trên là First_Car.

    2. Chức năng phải hoạt động với bất kỳ đối tượng tương tự nào.

    Chức năng kiểm tra đối tượng - đúng hay sai

    /*Đối tượng thứ 1*/
    var first_Car = (
    tạo: "VAZ",
    mô hình: 2106,
    năm: 1980,
    màu be màu",
    hành khách: 5,
    có thể chuyển đổi: sai,
    số dặm: 80000
    }

    /*Đối tượng thứ 2*/
    var giây_Car = (
    tạo: "VW",
    mô hình: "Passat b3",
    năm: 1990,
    màu sắc: "sao Hải Vương",
    hành khách: 5,
    có thể chuyển đổi: sai,
    số dặm: 160000
    }

    /*Đối tượng thứ 3*/
    var thứ ba_Car = (
    hãng: "Hyundai",
    mô hình: "Solaris",
    năm 2012,
    màu: "nhựa đường ướt",
    hành khách: 5,
    có thể chuyển đổi: sai,
    số dặm: 15000
    }


    chức năng good_Car(xe) (
    nếu (xe. năm< 2000 ){
    trả về sai;
    }
    khác nếu (xe. số dặm > 50000 )(
    trả về sai;
    }
    khác(
    trả về sự thật;
    }
    }

    /* Gọi hàm và xuất kết quả */
    var result = good_Car (third_Car );

    tài liệu.

    viết (kết quả);

    • Nhận xét về giải pháp: Vì vậy chúng ta có ba đối tượng(ba chiếc xe)
    • Hàm good_Car có một tham số car , có thể là bất kỳ đối tượng nào (ô tô): first_Car , two_Car hoặc Third_Car : hàm good_Car(car) .
    • Phần thân của Hàm good_Car chứa một điều kiện theo đó:

      Nếu giá trị tài sản năm của đối tượng ô tô nhỏ hơn 2000 (hay nói cách khác: nếu xe có tuổi đời dưới 2.000 năm), thì hàm trả về false;

      Mặt khác, nếu giá trị thuộc tính quãng đường của đối tượng ô tô lớn hơn 50000 (nếu xe đã đi trên 50.000), thì hàm trả về false;

      Nếu không thì hàm trả về true.

    • Tiếp theo, chúng ta gọi hàm và chỉ định đối tượng Third_Car làm tham số (xe thứ ba), vượt qua bài kiểm tra thành công. Kết quả của hàm được lưu trữ trong biến kết quả:
      var result = good_Car(third_Car); .
    • Biến kết quả được hiển thị trên màn hình;
    • Hai đối tượng khác (xe hơi) sẽ không đáp ứng được yêu cầu của điều kiện.
    Tối ưu hóa mã

    Hãy tiếp tục làm việc với các đối tượng trong javascript.

    Vì vậy, chức năng được thảo luận ở trên khi kiểm tra đối tượng (ô tô) trả về đúng hoặc sai (đúng hay sai).

    Bạn có thể cải thiện một chút chất lượng nhận thức về giải pháp cho vấn đề đang được xem xét, nghĩa là thay vì đúng hoặc sai, hãy hiển thị một số văn bản. Để làm điều này, chúng tôi sẽ tạo điều kiện để phân tích kết quả.

    /*Đối tượng thứ 1*/
    var first_Car = (
    tạo: "VAZ",
    mô hình: 2106,
    năm: 1980,
    màu be màu",
    hành khách: 5,
    có thể chuyển đổi: sai,
    số dặm: 80000
    }

    /*Đối tượng thứ 2*/
    var giây_Car = (
    tạo: "VW",
    mô hình: "Passat b3",
    năm: 1990,
    màu sắc: "sao Hải Vương",
    hành khách: 5,
    có thể chuyển đổi: sai,
    số dặm: 160000
    }

    /*Đối tượng thứ 3*/
    var thứ ba_Car = (
    hãng: "Hyundai",
    mô hình: "Solaris",
    năm 2012,
    màu: "nhựa đường ướt",
    hành khách: 5,
    có thể chuyển đổi: sai,
    số dặm: 15000
    }

    /*Hàm kiểm tra đối tượng */
    chức năng good_Car(xe) (
    nếu (xe. năm< 2000 ){
    trả về sai;
    }
    khác nếu (xe. số dặm > 50000 )(
    trả về sai;
    }
    khác(
    trả về sự thật;
    }
    }


    var result = good_Car (third_Car );

    nếu (kết quả) (
    tài liệu. viết ("Bạn có một chiếc xe tốt: " + Third_Car . năm + " năm sản xuất, với số km đã đi " +third_Car .mileage + " km." );
    }
    khác(
    tài liệu. write("Chúng tôi sẽ không nói về chiếc xe của bạn...");
    }

    Lời giải có điều kiện cho kết quả - Kết quả...

    Điều kiện để phân tích kết quả như sau.

    • Biểu thức if(result) là dạng viết tắt của biểu thức
      if(kết quả == đúng) .
    • Nếu kết quả của hàm good_Car là đúng thì chúng tôi hiển thị cụm từ: “Bạn có một chiếc xe tốt: 2012, đã đi được 15.000 km,” trong đó

      2012 và 15000 là các giá trị của thuộc tính năm và quãng đường của đối tượng Third_Car.

    • Nếu điều kiện kiểm tra kết quả tạo ra giá trị sai false thì chúng ta sẽ thấy: “We won’t talk about your car…”. Tức là đối tượng được đề cập (ô tô)đã không vượt qua bài kiểm tra.
    Tối ưu hóa mã - Tiếp tục - Thêm chức năng

    Nhưng đó không phải là tất cả. Hãy xem kỹ đoạn mã để gọi hàm và phân tích kết quả:

    /* Gọi hàm và phân tích kết quả */
    var result = good_Car(third_Car );

    nếu (kết quả) (
    document.write("Bạn có một chiếc xe tốt: " +third_Car .year + " năm sản xuất, với số km đã đi " +third_Car .mileage + " km.");
    }
    khác(
    document.write("Chúng tôi sẽ không nói về chiếc xe của bạn......");
    }

    Đây là đối tượng thứ ba_Car (xe thứ ba) chỉ ra ba lần:

    • Lần đầu tiên hàm good_Car được gọi, nó được chỉ định làm tham số: good_Car(third_Car) .
    • Và sau đó nó xuất hiện hai lần nữa khi chúng ta truy cập để chỉ ra các thuộc tính của nó: three_Car.year và Third_Car.mileage .

    Tôi không thích điều này vì khi phân tích một đối tượng khác (xe hơi) chúng ta cũng sẽ phải gọi tên anh ấy ba lần!!!

    Để đạt được chỉ báo một lần về đối tượng được phân tích, bạn cần cả kết quả của hàm good_Car và phân tích kết quả này (đó là tất cả) đưa vào một chức năng khác.

    /*Đối tượng thứ 1*/
    var first_Car = (
    tạo: "VAZ",
    mô hình: 2106,
    năm: 1980,
    màu be màu",
    hành khách: 5,
    có thể chuyển đổi: sai,
    số dặm: 80000
    }

    /*Đối tượng thứ 2*/
    var giây_Car = (
    tạo: "VW",
    mô hình: "Passat b3",
    năm: 1990,
    màu sắc: "sao Hải Vương",
    hành khách: 5,
    có thể chuyển đổi: sai,
    số dặm: 160000
    }

    /*Đối tượng thứ 3*/
    var thứ ba_Car = (
    hãng: "Hyundai",
    mô hình: "Solaris",
    năm 2012,
    màu: "nhựa đường ướt",
    hành khách: 5,
    có thể chuyển đổi: sai,
    số dặm: 15000
    }

    /*Hàm kiểm tra đối tượng */
    chức năng good_Car(xe) (
    nếu (xe .năm< 2000){
    trả về sai;
    }
    khác nếu (ô tô .mileage > 50000)(
    trả về sai;
    }
    khác(
    trả về sự thật;
    }
    }

    /* Nhập kết quả của hàm good_Car và Phân tích kết quả đó vào hàm khác */
    hàm itog(car )(
    var result = good_Car(car);

    Nếu (kết quả) (
    document.write("Bạn có một chiếc xe tốt: " + xe .năm + " năm sản xuất, với số km đã đi " + xe .mileage + " km.");
    }
    khác(
    document.write("Chúng tôi sẽ không nói về chiếc xe của bạn......");
    }
    }

    itog(thứ ba_Car );

    Giải pháp sử dụng chức năng khác - Kết quả...

    Bạn có một chiếc xe tốt: sản xuất năm 2012, đã đi được 15.000 km.

    Xin chào tất cả những ai đọc ấn phẩm này. Hôm nay tôi muốn hướng dẫn bạn một công cụ chính của ngôn ngữ - đối tượng JavaScript. Hãy để tôi nhắc bạn rằng js là trình duyệt chéo và hoạt động trên tất cả các hệ điều hành (windows, mac os, v.v.). Không giống như các ngôn ngữ lập trình hướng đối tượng, việc triển khai các đối tượng trong js khác biệt đáng kể so với chức năng thông thường và các biến thể trong việc sử dụng các thể hiện, chẳng hạn như trong C#.

    Do đó, sau khi đọc bài viết hiện tại, bạn sẽ tìm hiểu các đặc điểm phân biệt chính của các đối tượng tập lệnh, tìm hiểu những cách có thể tạo, cập nhật và xóa chúng. Tôi cũng sẽ đề cập đến chủ đề thuộc tính, phương thức và hàm tạo, đồng thời nói về lệnh hữu ích và tất nhiên một chút về thừa kế. Tôi nghĩ đã đến lúc bắt đầu học!

    Đối tượng trong JavaScript là gì và nó có những khả năng gì?

    Trong js, các đối tượng là các mảng kết hợp đơn giản (chúng còn được gọi là hàm băm).

    Mảng kết hợp là gì?

    Đây là cấu trúc dữ liệu lưu trữ một lượng thông tin nhất định liên quan đến và mô tả một phần tử cụ thể. Tất cả dữ liệu được cấu trúc và kết nối với nhau dưới dạng “key => value”.

    Ví dụ, bạn cần mô tả ô tô. Sau đó, bạn tạo một đối tượng auto và mô tả các đặc điểm của nó trong một mảng. Tôi quyết định mô tả kiểu dáng của chiếc xe (tên), màu sắc (màu sắc) và giá thành (giá cả). Dưới đây tôi đã đính kèm mã để thực hiện tác vụ được mô tả.

    1 2 3 4 5 var avto = (tên: “BMW 116i”, màu: “đen”, giá: 588000 );

    var avto = (tên: “BMW 116i”, màu: “đen”, giá: 588000 );

    Ở đây bạn thấy một cách để tạo một đối tượng có tên là “avto”. Tên, màu sắc và giá cả là những chìa khóa có thể được sử dụng trong quá trình viết ứng dụng.

    Tôi đã đi trước với ví dụ này, vì vậy bây giờ chúng ta hãy xem xét mọi thứ theo thứ tự.

    Bạn có thể tạo một đối tượng theo nhiều cách:

    var auto = (); hoặc var auto = new Object();

    Trong cả hai trường hợp, một đối tượng trống có tên đã biết sẽ được tạo, nhưng tùy chọn đầu tiên được sử dụng thường xuyên hơn nhiều vì nó ngắn hơn và thuận tiện hơn để viết.

    Tất cả về tài sản

    Bây giờ bạn cần điền vào đối tượng trống các tham số. Để làm điều này, bạn cần thêm các thuộc tính mà tôi còn gọi là khóa ở trên. Một lần nữa, có hai cách để khai báo thuộc tính.

    Tôi muốn lưu ý rằng JavaScript không có khuôn khổ nghiêm ngặt để tạo và khởi tạo các tham số đó. Các thuộc tính mới có thể xuất hiện xuyên suốt mã, cũng như chúng có thể bị xóa và cập nhật.

    Do đó, bạn có thể tạo tất cả các khóa cùng một lúc hoặc khai báo chúng khi chúng có sẵn. Và ngay cả khi trong khi viết chương trình, bạn đề cập đến các khóa không tồn tại thì sẽ không có lỗi. Trong trường hợp này, “không xác định” sẽ được trả về.

    Cách đầu tiên.

    Tạo và truy cập các thuộc tính bằng dấu chấm. Để thực hiện tùy chọn này, bạn cần viết tên của đối tượng, sau đó gán tên khóa cho nó thông qua dấu chấm và sau đó gán một số giá trị thông qua dấu bằng:

    avto.name = “BMW 116i”

    Nhưng trong phương pháp này, bạn sẽ thêm một phần tử nữa vào các khóa hiện có:

    Phương pháp này được sử dụng khi tên thuộc tính đã được biết và cần được thực hiện hành động nhất định với ý nghĩa.

    Cách thứ hai.

    Không khác gì so với lần đầu tiên, nếu bạn so sánh mục đích của họ. Tuy nhiên, phương pháp này có một lợi thế nhỏ. Đối với tùy chọn này, dấu ngoặc vuông được sử dụng:

    avto[“tên”] = “BMW 116i”

    Một bổ sung thú vị là khả năng tạo tên thuộc tính ở dạng bất kỳ chuỗi nào. Ví dụ,

    avto[“tên xe”] = “BMW 116i”

    Làm việc với các khóa thông qua dấu ngoặc vuông được sử dụng khi một số tham số được người dùng nhập và lưu trữ trong các biến hoặc khi không biết trước tên của các thuộc tính. Ví dụ: người dùng yêu cầu giá của một chiếc ô tô đã chọn. Phần tử được gọi sẽ được ghi vào biến và giá được gửi để phản hồi:

    var auto = (); avto.name = "BMW_116i"; avto.price = 588000; khóa var = "giá"; // giá xe được yêu cầu notification(avto);

    Bây giờ hãy chuyển sang xóa thuộc tính. Mọi thứ ở đây rất đơn giản. Để xóa, sử dụng lệnh xóa. Vì vậy, nếu bạn thêm 2 dòng sau vào ví dụ cuối cùng bên dưới:

    xóa auto.price;

    cảnh báo (tự động);

    Sau đó, khi gọi cảnh báo lần thứ hai, hộp thoại sẽ hiển thị “không xác định”.

    Một vài lời về sự nhỏ gọn

    Ở giai đoạn hiện tại, tôi đã hướng dẫn bạn cách tạo một đối tượng và mô tả các thuộc tính của nó. Tôi đã đính kèm các trường hợp thử nghiệm vào đây, nhưng những độc giả chu đáo nhất trong số các bạn đã nhận thấy rằng mã chương trình đầu tiên có phần khác so với tất cả các mã khác.

    Và tất cả là do nó sử dụng cách biểu diễn dữ liệu nhỏ gọn. Đây là một phương pháp khai báo khóa rất phổ biến vì nó viết ngắn hơn và dễ hiểu hơn bằng trực quan.

    Chúng ta hãy đi qua tài sản của chúng tôi

    Trong JavaScript, bạn có thể nhanh chóng lặp qua các thuộc tính đã tạo. Một cơ chế đặc biệt đã được cung cấp cho việc này, hay được gọi là chu trình.

    Nếu bạn quen thuộc với các ngôn ngữ lập trình khác, bạn biết rằng hầu hết các vòng lặp thường được tạo bằng cách sử dụng từ for , sau đó trong dấu ngoặc đơnđiều kiện để liệt kê các phần tử được chỉ định.

    Trong js nó nhắc nhở nó vẻ bề ngoài vòng lặp foreach từ ngôn ngữ C#. Kiểm tra thiết kế chung:

    for (var obj in object) ( // thực hiện tìm kiếm)

    trong đó obj chịu trách nhiệm về tên của các khóa được liệt kê,

    đối tượng – cho các giá trị của chúng.

    Và bây giờ đây là một ví dụ cụ thể cho bạn.

    1 2 3 4 5 6 7 8 var avto = (tên: “BMW 116i”, màu: “đen”, giá: 588000 ); for (var obj trong đối tượng) ( cảnh báo(obj + ://: + object) )

    var avto = (tên: “BMW 116i”, màu: “đen”, giá: 588000 ); for (var obj trong đối tượng) ( cảnh báo(obj + ://: + object) )

    Đã đến lúc làm quen với các phương pháp

    Ngôn ngữ kịch bản cung cấp khả năng tạo ra các phương thức. Đây là một cơ chế hoàn toàn đơn giản mà bất cứ lúc nào bạn cũng có thể thêm một hoặc nhiều phương thức vào bất kỳ đối tượng nào để mở rộng khả năng của các mảng kết hợp đã tạo. Chúng còn được gọi là thuộc tính hàm.

    Bản thân Js rất năng động và tuyệt vời ở một mức độ nào đó. Đây là cách bạn có thể tạo các phần tử thuộc nhiều loại khác nhau. Khi học ngôn ngữ này, bạn không cần phải ghi nhớ các cấu trúc phức tạp vì nhiều cách khai báo rất giống nhau.

    Vì vậy, để tạo một phương thức, bạn cần khai báo một đối tượng, sau đó bắt đầu viết lệnh giống hệt như tạo thuộc tính. Tuy nhiên, sau “=” nó không còn là giá trị được ghi nữa mà là từ khóa hàm (biến). Và sau đó các hành động được liệt kê trong dấu ngoặc nhọn.

    Đây là cách thực hiện cơ chế này:

    var avto =() avto.name = “BMV” avto.year = 1999 avto.drive = function(k) ( cảnh báo(“Xe đã đi qua”+n+“ km.”)) avto.drive(300) avto. lái xe (450)

    Như bạn có thể thấy, ví dụ này chứa các thuộc tính và phương thức có lệnh gọi ban đầu giống hệt nhau.

    JS cũng có hàm tạo phải không?

    Vâng thưa ngài! Trong ngôn ngữ này, bất kỳ thứ gì sử dụng từ khóa "mới" sẽ tự động trở thành hàm tạo. Như vậy ở trên các bạn đã thấy khai báo một đối tượng rỗng có dạng: avto = new Object();. Đây là hàm tạo.

    Để rõ ràng, hãy xem xét các dòng dưới đây.

    var bob = Đối tượng mới();

    bob.name = "Bob Smith";

    Tuy nhiên, đây không phải là toàn bộ kho vũ khí có khả năng. Trong js, bạn có thể tạo các hàm tạo của riêng mình và sau đó sử dụng chúng để khai báo các đối tượng mới.

    Vì vậy, tôi muốn “tạo” một công cụ xây dựng tùy chỉnh cho những chiếc ô tô hiện có. Xin lưu ý rằng tên phải được viết bằng chữ in hoa. Đây là đặc điểm nổi bật của chức năng. Để làm được điều này tôi viết phần triển khai phần mềm sau:

    chức năng Auto (tên, giá) (

    this.name = tên;

    giá này = giá;

    Bây giờ, khi bạn tạo số lượng đối tượng không giới hạn và áp dụng hàm tạo này cho chúng, tất cả chúng sẽ thuộc cùng một lớp. Ví dụ:

    var car1 = new Avto("BMW", 650000);

    var car2 = new Avto("Audi", 520000);

    Ngoài ra, bạn có thể tạo các phương thức bên trong hàm tạo.

    Tính năng kế thừa trong JavaScript

    Thông thường, trong nhiều ngôn ngữ, tính kế thừa dựa trên các lớp có thể kế thừa lẫn nhau. Sau đó, bạn có thể nghe thấy các biểu thức như “lớp tổ tiên”, “lớp con”, v.v.

    Tuy nhiên, trong js mọi thứ lại khác. Đây là nơi các đối tượng được kế thừa.

    Tất cả sự kế thừa đều dựa trên tham chiếu nội bộ giữa các đối tượng, được gọi là "nguyên mẫu". Nếu bạn thêm “.prototype” vào một phương thức bằng dấu chấm, sau đó nhập tên của nguyên mẫu thì tất cả các đối tượng của phương thức đã chọn sẽ được kế thừa từ nguyên mẫu này.

    Hãy chuyển sang một ví dụ.

    function Transport (name) ( this.name = name this.canDrive = true ) var Transport = new Transport ("avto") // tạo một đối tượng vận chuyển function Bike (name) ( this.name = name ) Bike.prototype = Transport // chỉ định rằng tất cả các đối tượng mới của lớp này sẽ sử dụng phương tiện giao thông bike1 = new Bike ("for_sport") bike2= new Bike ("for_child") console.log(bike1.name) console.log(bike2.name) console .log (bike1.canDrive)

    Tôi đoán tôi sẽ kết thúc ở đây. Tôi đã kể cho bạn nghe về các khía cạnh cơ bản của ngôn ngữ kịch bản. Tuy nhiên, đây chỉ là những kiến ​​thức hời hợt. Tiếp theo chúng ta sẽ đi sâu hơn. Trong lúc chờ đợi, đừng quên gia nhập hàng ngũ những người đăng ký của tôi và chia sẻ liên kết tới bài viết với bạn bè của bạn. Chúc may mắn!

    Tạm biệt!

    Trân trọng, Roman Chueshov

    Đọc: 97 lần