logo

Đang load dữ liệu

logo devmaster

VIỆN CÔNG NGHỆ VÀ ĐÀO TẠO DEVMASTER

Đào tạo - Phần mềm - Cho thuê nhân sự

  • 0969.609.003
  • 0978.611.889
  • Trang chủ
  • Các khoá đào tạo
    • Chuyên đề WEB - PHP

      • Lập trình web với HTML5 - CSS3- JQuery - Bootstrap - Ajax - [36 giờ]
      • Lập trình web frontend - reactjs - [75 giờ]
      • Lập trình web với mã nguồn mở PHP&MYSQL - PHP FRAMEWORK [126 giờ]

      Chuyên đề Mobile

      • Lập trình Games/Apps trên nền tảng Android - [120 giờ]
      • Lập trình Games/Apps trên nền tảng IOS - [120 giờ]

      Chuyên đề JAVA

      • Ngôn ngữ lập trình hướng đối tượng với java - [40 giờ]
      • Lập trình ứng dụng với java - [100 giờ]
      • Lập trình web site với java framework (JPA, HIBERNATE, SPRING MVC, SPRINGBOOT) - [276 giờ]

      Chuyên đề NETWORK/SECURITY

      • Khoá học Quản trị hạ tầng mạng CCNA v6 - [72 giờ]
      • Khoá học quản trị hệ thống với Windows SERVER 2012- [72 giờ]
      • Chuyên gia bảo mật hệ thống CompTIA + - [110 giờ]

      Chuyên đề .NET

      • Nền tảng lập trình hướng đối tượng với C# - [40 giờ]
      • Lập trình ứng dụng WINDOWS FORM - [100 giờ]
      • Lập trình Web với ASP.NET MVC 5, WebAPI - [145 giờ]

      Chuyên đề khác

      • Ngôn ngũ lập trình C/C++ - [80 giờ]
  • Lập trình cho trẻ em
  • Dịch vụ
    • Đào tạo theo như cầu
    • Cung cấp thiết bị - Phần mềm
    • Tư vấn - Thiết kế mạng hạ tầng
    • Tư vấn - Triển khai dịch vụ mạng
    • Tư vấn - Tư vấn, triển khai giám sát hệ thống
    • Thực tập dự án
  • Lịch khai giảng
  • Tin tức
    • Tin tức và sự kiện
    • Tin hoạt động
    • Tin công nghệ
    • Hội thảo, workshop, Codecam
    • Thông tin việc làm
    • Cẩm nang chia sẻ kiến thức
  • Tiện ích
  • Liên hệ

Cẩm nang chia sẻ kiến thức

Dec - 2020

07

5 quy tắc binding trong JavaScript

Cẩm nang chia sẻ kiến thức

Khái niệm “this” trong JavaScript là một trong những khía cạnh khó hiểu nhất của ngôn ngữ này. Tuy nhiên lại là nhân tố quan trọng để viết code “advance”, nâng cao hơn. Trong JS, this cho phép:

  • Sử dụng lại function trong các ngữ cảnh khác nhau
  • Xác định tập trung vào object nào khi gọi method.

Nhắc tới this thì điều đầu tiên phải làm đó là biết gọi funtion nào, bởi sẽ không biết cái gì ở bên trong this cho tới khi function được gọi. Và các trường hợp của this có thể chia thành 5 khía cạnh binding khác nhau.

Binding là gì

Trong JavaScript thì Lexical Environment hay nói theo nghĩa đen là môi trường từ vựng, cũng như là môi trường chứa đựng code được viết ra theo mặt vật lý (physically) . Hãy xem ví dụ bên dưới, tên biến bên trong function sayName( ) là lexically

function sayName() {
  let name = 'someName';
  console.log('The name is, ', name);
}

Trong đó Execution Context thì liên quan đến code hiện thời đang chạt và những thứ giúp code hoạt động. Có thể có nhiều lexical environments có sẵn nhưng chỉ có một cái đang chạy lúc này, và được Execution Context quản lý.

 

 

Mỗi Execution Context lại chứa một Environment Record Binding trong JavaScript có nghĩa là ghi lại identifier (variable và tên function) trong một Environment Record cụ thể.

Lưu ý: Binding giúp kết hợp identifier (variable và tên function) với this cho  một execution context .

Khúc này còn hơi rắc rối nhưng những phần sau sẽ giải thích rõ hơn.

Quy tắc 1: Implicit Binding hoạt động như thế nào?

Trong implicit binding thì cần phải xem đối tượng bên trái của hàm sử dụng dấu chấm (dot operater), từ đó xác định được this đang tham chiếu tới cái gì.

let user = {
    name: 'Tapas',
    address: 'freecodecamp',
    getName: function() {
        console.log(this.name);
    }
};

user.getName();

Ví dụ này thì this đang trỏ tới user object, bởi vì bên trái hàm dấu chấm là function getName (), ta thấy có user object, vì vậy this.name trong console sẽ hiển thị Tapas.

Một ví dụ khác

function decorateLogName(obj) {
      obj.logName = function() {
          console.log(this.name);
      }
  };

  let tom = {
      name: 'Tom',
      age: 7
  };

  let jerry = {
      name: 'jerry',
      age: 3
  };

  decorateLogName(tom);
  decorateLogName(jerry);

  tom.logName();
  jerry.logName();

Trong ví dụ này thì có 2 object, tom và jerry. Và chúng được decorate (nâng cao) bằng cách đính kèm method logName( )

Khi gọi hàm tom.logName( ) , object tom nằm bên trái dấu chấm cuả function logName( ) . Nên this sẽ trỏ tới object tom và nhận giá trị của tom ( this.name tương đương với tom). Tương tự khi gọi hàm jerry.logName( )

Quy tắc 2: Explicit Binding hoạt động như thế nào?

JavaScript tạo môi trường để thực hiện code mà chúng ta viết. Trong đó nó đảm nhiệm memory creation (dành cho variables, functions, objects) trong creation phase. Cuối cùng nó chãy code trong execution phase. Lúc này môi trường mới được Execution Context.

Có nhiều loại environment trong JavaScript application. Mỗi execution context thực hiện, chạy lệnh độc lập với nhau. Nhưng sẽ có lúc cần sử dụng thứ này trong execution context này trong cái context khác. Lúc này explicit binding sẽ pht huy công dụng.

Trong explicit binding, chúng ta có thể gọi function với object khi funtion đó nằm ngoài execution context của object đó.

Để thực hiện explicit biding thì có 3 method đó là call(), apply() và bind().

Hàm call() hoạt động thế nào

Với phương thức call() thì context với function được gọi sẽ được chuyển tới called dưới dạng tham số (parameter).

let getName = function() {
     console.log(this.name);
 }
 
let user = {
   name: 'Tapas',
   address: 'Freecodecamp'  
 };

getName.call(user);

Ở đây, hàm call() sẽ được gọi trên function getName(). Function getName() nhận giá trị this.name. Nhưng this trong đây là gì? Lúc này sẽ được quyết định bởi giá trị đã được chuyển đến hàm call().

Với trường hợp này, this sẽ được bind đến user object bởi vì đã chuyển user như một tham số đến hàm call(). Vì vậy this.name sẽ nhận giá trị của thuộc tính name của user object, Tapas. 

Ví dụ trên mới chỉ chuyển một argument tới hàm call(), nhưng thực tế có thể chuyển nhiều argument như sau:

let getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }

let user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

let hobbies = ['Swimming', 'Blogging'];
 
getName.call(user, hobbies[0], hobbies[1]);

Argument đầu tiên đuợc chuyển tới call() là object context với function đã được gọi. Những thuộc tính khác chỉ có thể là giá trị được sử dụng. Ở đây mình đang chuyển Swimming và Blogging là 2 thuộc tính tới function getName().

Tuy nhiên sẽ có trường hợp cần pass từng argument một trong call() thì sao? Lúc này sẽ tới lượt của apply().

Hàm apply() hoạt động thế nào

Cách mà apply() thực thi lệnh cũng tương đồng với call() nhưng cho phép pass argument thuận tiện hơn.

let getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }
 
let user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

let hobbies = ['Swimming', 'Blogging'];
 
getName.apply(user, hobbies);

Lúc này ta có thể chuyển một mảng (array) chứa argument luôn, tiện hơn nhiều so với việc chuyển từng cái.

Tips: nếu bạn cần chuyển một giá trị argument hay argument mà không có giá trị thì hãy dùng call(). Còn nếu chuyển nhiều giá trị argument thì dùng apply().

Hàm bind() hoạt động thế nào

Method bind() cũng tương tự như call() nhưng có 1 điểm khác biệt nhỏ. Thay vì gọi function trực tiếp thì bind() trả về một hàm mới.

let getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }

let user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

let hobbies = ['Swimming', 'Blogging'];
let newFn = getName.bind(user, hobbies[0], hobbies[1]); 

newFn();

Ở đây getName.bind() không gọi function getName() trực tiếp, nó trả về function mới, newFn và chúng ta đang gọi hàm dưới dạng newFn().

Quy tắc 3: New Binding

Từ khóa new được dùng để tạo một object mới từ constructor function.

let Cartoon = function(name, animal) {
     this.name = name;
     this.animal = animal;
     this.log = function() {
         console.log(this.name +  ' is a ' + this.animal);
     }
 };

Bạn có thể tạo nhiều object với từ khóa new như sau:

 let tom = new Cartoon('Tom', 'Cat');
 let jerry = new Cartoon('Jerry', 'Mouse');

Với quy tắc new biding, khi một function được gọi với từ khóa new, thì this bên trong function sẽ tham chiếu tới cái object mới được lập.

let tom = new Cartoon('Tom', 'Cat');

Đây là function Cartoon được gọi với từ khóa new. Thì this sẽ tham chiếu tới object mới, tom.

Quy tắc 4: Global Object Binding

Đoạn code dưới đây có kết quả thế nào? this tham chiếu tới cái gì?

let sayName = function(name) {
    console.log(this.name);
};

window.name = 'Tapas';
sayName();

Nếu this không giải quyết được với một trong những quy tắc binding, implicit, explicit hay new, thì this lúc này tham chiếu tới object window(global).

Tuy nhiên quy tắc strict mode của JavaScript sẽ không cho phép default binding như sau:

"use strict";
function myFunction() {
  return this;
}

Trường hợp này thì this là undefined.

Quy tắc 5: HTML Event Element Biding

Trong HTML event handlers, this tham chiếu tới element HTML nào nhận event đó.

<button onclick="console.log(this)">Click Me!</button>

Đây là giá trị trả về console khi click vào button:

"<button onclick='console.log(this)'>Click Me!</button>"

Bạn có thể thay đổi style của this:

<button onclick="this.style.color='teal'">Click Me!</button>

Nhưng hãy cẩn thận khi call function trên button click và dùng this bên trong function đó.

<button onclick="changeColor()">Click Me!</button>

và JavaScript:

function changeColor() {
  this.style.color='teal';
}

Đoạn code trên sẽ không trả kết quả như ý được, bởi theo như rule số 4 thì this sẽ tham chiếu tới object global, và không có object style để set màu.

Tổng kết

  • Với implicit binding thì this trỏ tới object bên trái của hàm dấu chấm.
  • Với explicit binding, chúng ta có thể gọi function với object khi function đó nằm ngoài execution context của object, có thể dùng các hàm như call(), apply(), bind().
  • Khi một function được gọi với từ khóa new thì this bên trong dunction sẽ trỏ tới object mới được lập.
  • Khi this không được giải quyết với implicit, explicit hay new thì this trỏ tới object window(global). Với strict mode của JavaScript, this trở nên undefined.
  • Trong HTML event handler thì this trỏ tới HTML element nào nhận event đó.

Tham khảo freeCodeCamp

Các bài viết cùng chủ đề

BÍ QUYẾT HỌC LẬP TRÌNH CHO CÁC BẠN ĐẦU NĂM HỌC MỚI ❤
BÍ QUYẾT HỌC LẬP TRÌNH CHO CÁC BẠN ĐẦU NĂM HỌC MỚI...
5 Phương pháp hay để mở rộng các dự án React của bạn một cách dễ dàng
5 Phương pháp hay để mở rộng các dự án React của b...
Lab06.1 - Data Access In ASPNET MVC 5
Lab06.1 - Data Access In ASPNET MVC 5
Lab05 - Data Validation and Annotation In ASPNET MVC 5
Lab05 - Data Validation and Annotation In ASPNET M...
Lab 04 - Model in ASP.NET MVC 5 - Phần tự thực hành
Lab 04 - Model in ASP.NET MVC 5 - Phần tự thực hàn...
Lab 04 - Model in ASP.NET MVC 5 - Bài 4.2
Lab 04 - Model in ASP.NET MVC 5 - Bài 4.2

Các khóa đào tạo chuyên đề

Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
Lập trình ứng dụng trên nền tảng android Lập trình ứng dụng trên nền tảng android
Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack

Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack
Lập trình ứng dụng với WINDOWS FORM Lập trình ứng dụng với WINDOWS FORM
Lập trình ứng dụng với JAVA (FORM) Lập trình ứng dụng với JAVA (FORM)
Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery
Lập trình frontend với reacjs (Full) Lập trình frontend với reacjs (Full)
Viện Công Nghệ Và Đào Tạo Devmaster

DEVMASTER ACADEMY

Địa chỉ: Tầng 6 - Tòa nhà VIỆN CÔNG NGHỆ
Số 25, Vũ Ngọc Phan - Láng Hạ - Đống Đa - Hà Nội

Hotline: 0969 609 003 | 0978 611 889

devmaster.contact@gmail.com

hna.tvchung@gmail.com

CÁC KHÓA HỌC CHUYÊN ĐỀ

  • Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
  • Lập trình ứng dụng trên nền tảng android
  • Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack
  • Lập trình ứng dụng với WINDOWS FORM
  • Lập trình ứng dụng với JAVA (FORM)
  • Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
  • Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery
  • Lập trình frontend với reacjs (Full)
Viện Công Nghệ Và Đào Tạo Devmaster

VIỆN CÔNG NGHỆ VÀ ĐÀO TẠO DEVMASTER - Học thực tế * Làm thực tế * Cam kết việc làm
Copyright by Ⓒ DEVMASTER 2015