Object javascript – Prototype Javascript-Kế thừa trong javascript

Object javascript
Object javascript

Tuyển lập trình viên Mobile lương upto $2500

1.Tìm hiểu object trong javascript

Bài 5: Function javascript – call()/apply()/bind()

Các kiểu dữ liệu trong javascript

  • Một object là một tập hợp các thuộc tính
  • Thuộc tính có thể là các biến(các trường) hoặc là function(các phương thức)
  • Object có thể nằm trong một object khác
  • Trong javascript , hầu như “mọi thứ” là object
  • Trừ kiểu nguyên thủy: boolean, number, string, undefined
  • Chúng ta có thể tạo đối tượng bao Boolean/Number/String

Ví dụ

var b = new Boolean(true)

  • Object có thể được tạo bằng từ khóa “new” hoặc cú pháp ({})
  • Ví dụ:

    var person = new Person(‘Alice’, 25)

 

var person = new Object()

   person.name = ‘Alice’

   person.age = 25

   person.sayHello = function() { console.log(‘Hello ‘ + this.name) }

 

var person = {

       name: ‘Alice’,

       age: 25,

       sayHello: function() { console.log(‘Hello ‘ + this.name) }

   }

  • Truy cập thuộc tính của  Object trong javascript  (access properties of object in javascript)
    • property1 OR obj[‘property1’]
    • method1() OR obj[‘method1’]()
  • Lưu ý đối tượng trong javascript không giống đối tượng Java/C#/Python
  • Sau khi được tạo, đối tượng Java/C#/Python không thể thêm hoặc bỏ đi các thuộc tính/các phương thức(rất khó khăn để chỉnh sửa)
  • Sau khi được tạo, đối tượng javascript có thể thêm hoặc bỏ đi các thuộc tính/các phương thức.

2.Object – Prototype Javascript

Prototype chain(chuỗi Prototype)

    • Không thực sự có “Class/Interface” trong javascript (không giống Java/C++/C#/Python)
      • class được định nghĩa bằng việc sử dụng từ khóa function  trong ES5
      • ES6 thì đã có từ khóa class, nhưng chỉ là cú pháp, mô hình kế thừa trong javascript vẫn dựa trên prototype
    • Mỗi object có một thuộc tính private (__proto__) , thuộc tính này giữ một liên kết tới một object khác được gọi là prototype của nó.
      • Đối tượng prototype đó có một prototype riêng của nó, và cứ thế tiếp tục cho tới khi  một đối tượng đạt được với null là prototype của nó. Với định nghĩa này, null không có prototype, và đóng vai trò như liên kết cuối cùng trong chuỗi prototype này.
    • Đối tượng Prototype được chia sẻ giữa tất cả đối tượng những cái mà được khởi tạo từ một class.
      • Nếu chúng ta thay đổi thuộc tính (fields/methods) của of Person.prototype, thì sự thay đổi này sẽ áp dụng cho tất cả  instances của  class Person

// constructor

function Person(namenationality) {

  this.name = name;

  this.nationality = nationality;

}

var p1 = new Person(“khoibv”, “Vietnam”);

Person.prototype.sayHi = function() {

  console.log(this.name + ” come from ” + this.nationality);

};

var p2 = new Person(“yamamoto”, “Japan”); 

p1.sayHi(); // khoibv come from Vietnam

p2.sayHi(); // yamamoto come from Japan

ở ví dụ trên  phương thức sayHi được thêm vào class sau khi p1 được tạo. Nhưng p1 vẫn gọi được phương thức, bằng cách đối tượng prototype được chia sẻ cho tất cả đối tượng của class Person.

    •  Object.prototype.__proto__ === null     (JavaScript Object có  prototype, nhưng không có cha của Object)

Chuỗi prototype – Sự kế thừa(Inheritance)

Chúng ta sẽ xem một class kế thừa một class khác sử dụng prototype như thế nào nhé.

Cụ thể là class Student kế thừa class Person bằng 2 cách bên dưới:

    1. Gọi tới hàm khởi tạo của lớp cha(superclass) trong hàm khởi tạo của class con.

Person.call(this, <arguments>)

    1. Thêm vào chuỗi prototype

Student.prototype = Object.create(Person.prototype)

Làm thế nào để gọi phương thức của class cha(super class). Cụ thể làm thế nào Student gọi phương thức sayHi().

Đầu tiên javacript kiểm tra sayHi() có được chứa trong object Student không, thì thấy không có.

Tiếp theo Js kiểm tra sayHi() có được chứa trong prototype của đối tượng Student(chính là Person), và Js tìm thấy sayHi() trong Person.

Js thực thi Person.sayHi()

function Student(name, nationality, university) {

  Person.call(this, name, nationality); // 1. call Person’s constructor

  this.university = university;

}

Student.prototype = Object.create(Person.prototype); // 2. add prototype chain

Student.prototype.introduce = function() {

  console.log(`${this.name} (${this.nationality}) is student of ${this.university}`);

};

let s1 = new Student(“Julia”, “USA”, “MIT”);

s1.sayHi(); // Julia come from USA

s1.introduce(); // Julia (USA) is student of MIT

Chúng ta cùng xem một ví dụ nữa về prototype của object nhé.

Khai báo class

function Person(name, age) {

    // This is constructor

    this.name = name;

    this.age = age;

}

Person.prototype = {

    getName: function() {

        return this.name;

    },

    getAge: function() {

        return this.age;

    }

};

Khai kháo Object

var alice = new Person(“Alice”, 25); // Object

var bill = new Person(“Bill”, 30); // Another object

/* Modify the class, all instances will have this method. */

Person.prototype.getGreeting = function() {

    return “Hi ” + this.getName() + “!”;

};

/* Modify a specific instance, only alice has this method. */

alice.displayGreeting = function() {

    alert(this.getGreeting());

};

alice.displayGreeting(); // Hi Alice!

bill.displayGreeting();  // Uncaught TypeError: bill.displayGreeting is not a function

ở ví dụ trên ta thấy phương thức getGreeting được thêm vào class sau khi 2 instance được tạo. Nhưng cả hai instance này vẫn có thể gọi được phương thức, dựa vào cách đối tượng prototype làm việc.

getGreeting  không bao gồm trong function khởi tạo, vì nó tạo ra một phương thức sao chép cho mọi đối tượng đơn lẻ được tạo bằng hàm khởi tạo.

Thay vào đó, chúng ta định nghĩa phương thức như một prototype của hàm khởi tạo, vì thế phương thức này được chia sẻ giữa các object.

displayGreeting không được khai báo như một prototype nhưng chỉ cho object ‘alice’, vì thế phương thức này chỉ khả dụng cho đối tượng ‘alice’, mà không khả dụng cho đối tượng “bill” => Vì lý do đó mà  khi gọi  bill.displayGreeting(); phát sinh lỗi.

 

Be the first to comment

Leave a Reply

Your email address will not be published.


*