HomeLập trìnhJavaScriptCách sử dụng...

Cách sử dụng các hàm gọi, áp dụng và liên kết trong JavaScript – với các ví dụ về mã


Trong bài viết này, tôi sẽ giải thích cách sử dụng lệnh gọi, áp dụng và liên kết trong JavaScript bằng các ví dụ đơn giản.

Chúng tôi cũng sẽ triển khai một ví dụ minh họa cách bạn có thể tạo chức năng bản đồ của riêng mình bằng chức năng áp dụng.

Không chần chừ nữa, chúng ta hãy bắt đầu.

Mục lục

điều kiện tiên quyết

Dưới đây là một số điều bạn nên hiểu để tận dụng tối đa bài viết này:

Các định nghĩa

Hãy xem xét kỹ hơn các chức năng mà chúng ta sẽ nghiên cứu ở đây để hiểu chức năng của chúng.

Cuộc gọi là hàm giúp bạn thay đổi ngữ cảnh của hàm gọi. Theo thuật ngữ của giáo dân, nó giúp bạn thay thế giá trị của this bên trong một hàm với bất kỳ giá trị nào bạn muốn.

Áp dụng rất giống với call chức năng. Sự khác biệt duy nhất là trong apply bạn có thể chuyển một mảng dưới dạng danh sách đối số.

Trói buộc là một chức năng giúp bạn tạo một chức năng khác mà bạn có thể thực hiện sau này với ngữ cảnh mới là this đó được cung cấp.

Bây giờ chúng ta sẽ xem xét một số ví dụ cơ bản về các hàm call, apply và bind. Sau đó, chúng ta sẽ xem xét một ví dụ mà chúng ta sẽ xây dựng chức năng của riêng mình tương tự như chức năng bản đồ.

Cách sử dụng hàm gọi trong JavaScript

call là một chức năng mà bạn sử dụng để thay đổi giá trị của this bên trong một hàm và thực thi nó với các đối số được cung cấp.

Đây là cú pháp của call chức năng:


func.call(thisObj, args1, args2, ...)

Ở đâu,

  • chức năng là một hàm cần được gọi với một hàm khác this vật
  • thisObj là một đối tượng hoặc một giá trị cần được thay thế bằng this từ khóa hiện diện bên trong chức năng func
  • đối số1, đối số2 là các đối số được truyền cho hàm gọi với giá trị đã thay đổi this vật.

Lưu ý rằng nếu bạn gọi một chức năng mà không có bất kỳ thisObj thì JavaScript coi thuộc tính này là một đối tượng toàn cục.

Bây giờ chúng ta có một số bối cảnh xung quanh những gì call chức năng là, hãy bắt đầu bằng cách hiểu nó chi tiết hơn với một số ví dụ.

Cách gọi một hàm với các ngữ cảnh khác nhau trong JS

Hãy xem xét ví dụ dưới đây. Nó bao gồm 3 lớp – Car, Brand1Brand2.

function Car(type, fuelType){
	this.type = type;
	this.fuelType = fuelType;
}

function setBrand(brand){
	Car.call(this, "convertible", "petrol");
	this.brand = brand;
	console.log(`Car details = `, this);
}

function definePrice(price){
	Car.call(this, "convertible", "diesel");
	this.price = price;
	console.log(`Car details = `, this);
}

const newBrand = new setBrand('Brand1');
const newCarPrice = new definePrice(100000);

Nếu bạn nhìn kỹ, bạn có thể thấy rằng chúng tôi sử dụng call chức năng để gọi các Car hoạt động trong hai dịp. Thứ nhất, trong setBrand và sau đó trong definePrice chức năng.

Đọc thêm  Các phương pháp JavaScript này sẽ nâng cao kỹ năng của bạn chỉ sau vài phút

Trong cả hai chức năng này, chúng tôi gọi Car chức năng với this đối tượng đại diện cho chính các chức năng tương ứng. Ví dụ, bên trong setBrandchúng tôi gọi là Car chức năng với this đối tượng thuộc ngữ cảnh của nó. Trường hợp tương tự đối với definePrice.

Cách gọi một hàm không có đối số trong JS

Hãy xem xét ví dụ dưới đây:

const newEntity = (obj) => console.log(obj);

function mountEntity(){
	this.entity = newEntity;
	console.log(`Entity ${this.entity} is mounted on ${this}`);
}

mountEntity.call();

Trong ví dụ này, chúng tôi đã gọi hàm mountEntity với không thisObj tranh luận. Trong những trường hợp như vậy, JavaScript đề cập đến đối tượng toàn cục.

Cách sử dụng chức năng Áp dụng trong JavaScript

Các Apply chức năng rất giống với Call chức năng. Sự khác biệt duy nhất giữa callapply là sự khác biệt trong cách các đối số được thông qua.

Trong applyđối số, bạn có thể truyền đối số dưới dạng một mảng ký tự hoặc một đối tượng mảng mới.

Đây là cú pháp cho apply chức năng:

func.apply(thisObj, argumentsArray);

Ở đâu,

  • chức năng là một hàm cần được gọi với một hàm khác this vật
  • thisObj là một đối tượng hoặc một giá trị cần được thay thế bằng this từ khóa hiện diện bên trong chức năng func
  • đối sốArray có thể là một mảng đối số, đối tượng mảng hoặc đối số từ khóa chính nó.

Như bạn có thể thấy ở trên, các apply chức năng có các loại cú pháp khác nhau.

Cú pháp đầu tiên là một cú pháp đơn giản. Bạn có thể chuyển vào một mảng các đối số như bên dưới:

func.apply(thisObj, [args1, args2, ...]);

Cú pháp thứ hai là nơi chúng ta có thể truyền vào đối tượng mảng mới cho nó:

func.apply(thisObj, new Array(args1, args2));

Cú pháp thứ ba là nơi chúng ta có thể truyền vào từ khóa đối số:

func.apply(thisObj, arguments); 

đối số là một đối tượng đặc biệt có sẵn bên trong một hàm. Nó chứa các giá trị của các đối số được truyền cho một hàm. Bạn có thể sử dụng từ khóa này với apply chức năng để lấy bất kỳ số lượng đối số tùy ý.

Phần tốt nhất về apply là chúng ta không cần quan tâm đến số lượng đối số được truyền cho hàm gọi. Do tính chất năng động và linh hoạt của nó, bạn có thể sử dụng nó trong những tình huống phức tạp.

Hãy xem ví dụ tương tự như trên, nhưng lần này chúng ta sẽ sử dụng apply chức năng.

function Car(type, fuelType){
	this.type = type;
	this.fuelType = fuelType;
}

function setBrand(brand){
	Car.apply(this, ["convertible", "petrol"]); //Syntax with array literal
	this.brand = brand;
	console.log(`Car details = `, this);
}

function definePrice(price){
	Car.apply(this, new Array("convertible", "diesel")); //Syntax with array object construction
	this.price = price;
	console.log(`Car details = `, this);
}

const newBrand = new setBrand('Brand1');
const newCarPrice = new definePrice(100000);

Và đây là một ví dụ giới thiệu cách bạn sử dụng arguments từ khóa:

function addUp(){
		//Using arguments to capture the arbitrary number of inputs
    const args = Array.from(arguments); 
    this.x = args.reduce((prev, curr) => prev + curr, 0);
    console.log("this.x = ", this.x);
}

function driverFunc(){
    const obj = {
        inps: [1,2,3,4,5,6]
    }
    addUp.apply(obj, obj.inps);
}

driverFunc();

Cách sử dụng chức năng liên kết trong JavaScript

Các bind chức năng tạo một bản sao của một chức năng với một giá trị mới cho this trình bày bên trong chức năng gọi.

Đây là cú pháp cho bind chức năng:

func.bind(thisObj, arg1, arg2, ..., argN);

Ở đâu,

  • chức năng là một hàm cần được gọi với một hàm khác this vật
  • thisObj là một đối tượng hoặc một giá trị cần được thay thế bằng this từ khóa hiện diện bên trong chức năng func
  • arg1, arg2…argN – bạn có thể truyền 1 đối số cho hàm gọi hoặc nhiều hơn thế, tương tự như call chức năng.

Các bind sau đó trả về một chức năng mới bao gồm một bối cảnh mới cho this biến hiện diện bên trong chức năng gọi:

func(arg1, arg2);

Bây giờ chức năng này func có thể được thực hiện sau với các đối số.

Hãy xem một ví dụ kinh điển về cách sử dụng bind chức năng với sự trợ giúp của thành phần React dựa trên lớp:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 1
    };
  }
  handleCode() {
    console.log("HANDLE CODE THIS = ", this.state);
  }
  render() {
    return <button onClick={this.handleCode}>Click Me</button>;
  }
}

Hãy xem xét thành phần Ứng dụng ở trên. Nó cấu thành những điều sau đây:

  • constructor là một hàm được gọi là một lớp và được khởi tạo bằng một new từ khóa.
  • render là một hàm thực thi/kết xuất mã JSX.
  • handleCode là một phương thức lớp ghi lại trạng thái của thành phần.

Nếu chúng ta bấm vào Click Me thì chúng ta sẽ nhận được thông báo lỗi: Cannot read properties of undefined (reading 'state').

Bạn đã bao giờ tự hỏi tại sao vấn đề này xảy ra? 🤔🤔

Bạn có thể mong đợi rằng chúng ta có thể truy cập trạng thái của lớp kể từ handleCode là một phương thức lớp. Nhưng đây là điểm thu hút:

  • this bên trong handleCode không giống như của lớp this.
  • Bên trong một lớp học, this là một đối tượng thông thường có các phương thức lớp không tĩnh làm thuộc tính của nó. Nhưng mà this bên trong handleCode sẽ đề cập đến một ngữ cảnh khác.
  • Thành thật mà nói, giá trị của this trong kịch bản này phụ thuộc vào nơi các chức năng đang được gọi. Nếu bạn thấy, handleCode đang được kêu gọi onClick biến cố.
  • Nhưng ở giai đoạn này, chúng ta sẽ nhận được undefined cho bối cảnh của this có mặt bên trong handleCode chức năng.
  • Chúng tôi đang cố gắng gọi state thuộc tính có giá trị không xác định. Do đó, điều này dẫn đến lỗi trên.

Chúng tôi có thể khắc phục điều này bằng cách cung cấp ngữ cảnh phù hợp của this bên trong handleCode phương pháp. Bạn có thể làm điều này với bind phương pháp.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 1
    };
   this.handleCode = this.handleCode.bind(this); //bind this function
  }
  handleCode() {
    console.log("HANDLE CODE THIS = ", this.state);
  }
  render() {
    return <button onClick={this.handleCode}>Click Me</button>;
  }
}

Các bind sẽ tạo một chức năng mới và lưu trữ nó bên trong this đối tượng với một thuộc tính mới như handleCode. Bind sẽ đảm bảo rằng lớp học this bối cảnh được áp dụng cho this có mặt bên trong handleCode chức năng.

Cách tạo của riêng bạn map Chức năng

Bây giờ chúng ta đã có tất cả những thứ cần thiết, hãy bắt đầu bằng cách tạo own chức năng bản đồ. Trước tiên chúng ta hãy hiểu những thứ mà chúng ta sẽ cần để xây dựng own chức năng bản đồ.

Đây là cú pháp của map chức năng:

arr.map(func)

Ở đâu,

  • mảng là một mảng mà bản đồ được gọi.
  • chức năng là hàm cần chạy trên từng phần tử của mảng.

Chức năng cơ bản của một map chức năng rất đơn giản:

Đó là một hàm đi qua từng phần tử của một mảng và áp dụng hàm được truyền dưới dạng đối số. Kiểu trả về của bản đồ lại là một mảng với func được áp dụng trên mỗi phần tử.

Bây giờ chúng tôi hiểu các yêu cầu, vì vậy chúng tôi có thể chuyển sang tạo riêng của chúng tôi map chức năng. Đây là mã mới của chúng tôi map chức năng:

function newMap(func){
  let destArr = [];
  const srcArrLen = this.length;
  for(let i = 0; i < srcArrLen; i++){
    destArr.push(func.call(this, this[i]));
  }

  return destArr;
} 

Hãy hiểu chức năng trên từng chút một:

  • Hàm này chấp nhận một đối số được gọi là func. Nó chẳng là gì ngoài một hàm cần được gọi trên mỗi phần tử của một mảng.
  • Các phần khác của mã là khá tự giải thích. Chúng tôi sẽ tập trung vào dòng sau: destArr.push(func.call(this, this[i]));
  • Dòng này làm hai việc:
    1. Đẩy các thay đổi vào destArr
    2. Thực hiện func với sự giúp đỡ của call phương pháp. đây call phương pháp (như đã giải thích trong các phần trước) sẽ thực thi func phương thức với một giá trị mới cho this đối tượng có mặt bên trong func phương pháp.

Bây giờ chúng ta hãy xem cách chúng ta sẽ thực hiện newMap chức năng. Cách tiếp cận dưới đây để thêm một phương thức mới vào kiểu dữ liệu nguyên thủy hiện có không được khuyến nghị nhưng chúng tôi vẫn sẽ làm điều đó vì mục đích của bài viết này.

GHI CHÚ: không làm theo cách tiếp cận dưới đây trong mã sản xuất của bạn. Điều này có thể gây ra thiệt hại cho mã hiện có.

Object.defineProperty(Array.prototype, 'newMap', {
  value: newMap
}); 

defineProperty chúng tôi tạo một thuộc tính mới bên trong Array.prototype.

Khi điều này được thực hiện, chúng ta có thể bắt đầu thực hiện chức năng bản đồ mới của mình trên một mảng.

const arr = [1,2,3];
const newArr = arr.newMap(item => item + 1);
console.log(newArr);

Tóm lược

Bài viết này đã chỉ cho bạn chức năng gọi, áp dụng và liên kết có thể thực hiện thông qua các ví dụ.

Vì vậy, để nói ngắn gọn về các chức năng này:

  • Gọi, áp dụng và liên kết là các chức năng giúp bạn thay đổi ngữ cảnh của this từ khóa hiện diện bên trong chức năng gọi.
  • Chúng ta đã thấy cách mỗi chức năng có thể được gọi theo những cách khác nhau – ví dụ: với apply bạn có thể thực thi một hàm với một mảng các đối số và với call chức năng bạn có thể thực hiện tương tự nhưng các đối số được trải qua dấu phẩy.
  • Các chức năng này thực sự hữu ích trong các thành phần dựa trên lớp của React.

Cảm ơn bạn đã đọc!

theo tôi trên TwitterGitHub và LinkedIn.





Zik.vn – Biên dịch & Biên soạn Lại

spot_img

Create a website from scratch

Just drag and drop elements in a page to get started with Newspaper Theme.

Buy Now ⟶

Bài viết liên quang

DMCA.com Protection Status