Thứ hai, 25/02/2019 | 00:00 GMT+7

Xem xét Phạm vi, Ngữ cảnh, Tham chiếu Đối tượng và Thuyết minh trong JavaScript


Trong bài viết này, tôi muốn giải thích một số khái niệm phức tạp trong JavaScript có thể trở nên thực sự khó hiểu, tùy thuộc vào vị trí của bạn trong hành trình phát triển của bạn . Cụ thể, tôi sẽ thảo luận về các tham chiếu đối tượng, phạm vi, ngữ cảnh và khởi tạo trong JavaScript. Nó sẽ giúp bạn hiểu một số hành vi có thể có vẻ kỳ quặc với JavaScript.

Đầu tiên, một ví dụ để minh họa quan điểm:

[] === []
// false

Woah, những gì vừa xảy ra một mảng trống không bằng một mảng trống. JavaScript, bạn có thể nhầm lẫn làm sao!

Tham chiếu đối tượng

Khái niệm về tham chiếu đối tượng có thể rất phức tạp, ví dụ ở đây, ta hãy kiểm tra xem liệu object1object2 có giống nhau không:

let object1 = { value:10 };
let object2 = object1;
let object3 = { value: 10};
object1 === object2
//true

Ta nhận được true vì cả object1object2 đều trỏ đến cùng một dữ liệu tham chiếu trong bộ nhớ. Nếu ta kiểm tra xem object1object3 có giống nhau không:

object1 === object3
// false

Hấp dẫn! cả hai đều có giá trị như nhau nhưng tại sao chúng không giống nhau. Đó là bởi vì object3 tạo ra một tham chiếu khác trong bộ nhớ, không giống với object1 nên JavaScript coi cả hai đối tượng là khác nhau.

Để giải thích thêm, hãy tưởng tượng object1 được tạo như một địa chỉ trong bộ nhớ, sau đó object2 trỏ đến object1 tại cùng một địa chỉ. Trong khi object3 là một địa chỉ khác trong bộ nhớ. địa chỉ object1 không bao giờ có thể giống địa chỉ object3 .

Tham chiếu mảng

Quay lại ví dụ ban đầu về:

[] === []
// false

Trong Javascript, mảng thực sự là các đối tượng phía sau khung cảnh, vì vậy JavaScript xử lý [] đầu tiên như một đối tượng mới và lưu trữ tham chiếu trong bộ nhớ, sau đó lưu trữ [] thứ hai dưới dạng một tham chiếu khác trong bộ nhớ, vì vậy khi kiểm tra sự bằng nhau, hóa ra chúng không thể giống nhau.

Phạm vi và bối cảnh

Bối cảnh luôn bị nhầm lẫn với phạm vi. Phạm vi luôn được tạo khi gặp dấu ngoặc nhọn. Ví dụ: nếu ta tạo một hàm, một phạm vi mới sẽ được tạo:

function sampleScope() {
  let a = 'a';
  console.log(a);
}

Nếu ta tham chiếu đến biến a từ bên ngoài hàm sampleScope thì nó sẽ không được nhận dạng vì biến được xác định bên trong phạm vi hàm sampleScope .

Bối cảnh

Một ngữ cảnh khác với phạm vi, nó cho bạn biết đối tượng hiện tại mà ta đang tham chiếu. Ngữ cảnh được truy cập bằng cách sử dụng từ khóa này . Ví dụ: nếu ta ghi lại ngữ cảnh hiện tại mà ta đang ở từ console trong trình duyệt với như sau:

console.log(this);
// Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

Nó cho ta biết ta hiện đang ở trong các đối tượng window . Các this là một từ khóa đặc biệt của Javascript điểm đó dành tặng cho các đối tượng hiện tại hoặc bối cảnh:

this.alert('hello');
window.alert('hello);

Hai dòng trên về cơ bản giống nhau vì từ khóa this tham chiếu đến đối tượng window vì đó là ngữ cảnh hiện tại.

Nếu ta tạo một đối tượng mới như vậy:

const object4 = {
  a: function() {
    console.log(this);
  }
}

object4.a();

// {a: ƒ}

Ta thấy rằng nó đăng xuất ngữ cảnh hiện tại là ngữ cảnh object4 .

Thuyết minh

Giả sử ta muốn theo dõi các học sinh mà ta đã có trong lớp học bằng cách đặt tên và giới tính của họ, vì vậy ta lập mô hình một lớp học giống như sau:

class Student {
  constructor(name, gender){
    console.log(this);
    this.name = name;
    this.gender = gender;
  }
  introduceStudent() {
    console.log(`${this.name}, ${this.gender}`);
  }
}

Ta có một lớp mà ta đã tạo chấp nhận namegender và cũng có quyền truy cập vào một chức năng ghi lại tên của học sinh.

Bây giờ, giả sử ta muốn tạo một lớp trưởng mà không cần phải sao chép cùng một mã và thêm thông tin bổ sung, ta có thể mở rộng lớp Student trong khi tạo một lớp mới cho lớp trưởng, như sau:

class Rep extends Student{
  constructor(name, gender){
    super(name, gender);
  }
  introduceClassRep() {
    console.log(`${this.name}, ${this.gender}, and I'm a class rep`);
  }
}

Các extends từ khóa cho hoạt Javascript để thêm bất cứ điều gì bất động sản lớp kéo dài từ lớp hiện hành. Khi nào ta mở rộng một lớp, ta cũng cần gọi nó là phương thức khởi tạo, super cho ta sức mạnh để thực hiện điều đó.

Bây giờ, hãy tạo các thể hiện của cả hai lớp:

const student1 = new Student('jane', 'female');
const student2 = new Rep('cole', 'male');

Sau khi tạo các version mới này, bạn sẽ thấy rằng hai kết quả của console là khác nhau. Đó chỉ đơn giản là vì chúng là các thể hiện của các lớp khác nhau.

Kết luận

Với JavaScript, hành vi của các đối tượng thoạt đầu có vẻ khá phức tạp, nhưng việc hiểu các khái niệm gạch chân có thể mang lại cho bạn rất nhiều sức mạnh và tiết lộ sự đơn giản của gạch dưới.

Ta đã xem xét cách các tham chiếu đối tượng, ngữ cảnh, phạm vi và các version hoạt động trong JavaScript và ta đã chỉ ra cách sử dụng chúng. Hy vọng rằng bây giờ bạn đã hiểu rõ hơn về những khái niệm nâng cao hơn này! 🏋


Tags:

Các tin liên quan

Sử dụng JavaScript Mixins
2019-02-12
Đọc mã nguồn JavaScript, sử dụng AST
2019-02-09
JavaScript Biểu thức chính quy cho Người bình thường
2019-02-07
Mẫu kế thừa nguyên mẫu JavaScript
2019-02-01
Các mẫu hướng đối tượng JavaScript: Mẫu nhà máy
2019-01-23
Đối tượng, Nguyên mẫu và Lớp trong JavaScript
2019-01-10
Thủ thuật với JavaScript Hủy cấu trúc
2018-11-26
Đừng sợ theo dõi JavaScript
2018-10-17
Làm phẳng mảng trong Vanilla JavaScript với flat () và flatMap ()
2018-09-28
Cách sử dụng các phương thức đối tượng trong JavaScript
2018-08-03