Làm thế nào để truy cập đúng `this` bên trong một lệnh gọi lại?

Nov 29 2013

Tôi có một hàm khởi tạo đăng ký một trình xử lý sự kiện:

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', function () {
        alert(this.data);
    });
}

// Mock transport object
var transport = {
    on: function(event, callback) {
        setTimeout(callback, 1000);
    }
};

// called as
var obj = new MyConstructor('foo', transport);

Tuy nhiên, tôi không thể truy cập thuộc datatính của đối tượng đã tạo bên trong lệnh gọi lại. Có vẻ như thisnó không tham chiếu đến đối tượng đã được tạo mà là đối tượng khác.

Tôi cũng đã cố gắng sử dụng một phương thức đối tượng thay vì một hàm ẩn danh:

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', this.alert);
}

MyConstructor.prototype.alert = function() {
    alert(this.name);
};

nhưng nó cho thấy những vấn đề tương tự.

Làm cách nào để truy cập đúng đối tượng?

Trả lời

1910 FelixKling Nov 29 2013 at 13:13

Những gì bạn nên biết về this

this(hay còn gọi là "bối cảnh") là một từ khóa đặc biệt bên trong mỗi hàm và giá trị của nó chỉ phụ thuộc vào cách hàm được gọi chứ không phải cách / khi / nơi nó được định nghĩa. Nó không bị ảnh hưởng bởi phạm vi từ vựng như các biến khác (ngoại trừ các hàm mũi tên, xem bên dưới). Dưới đây là một số ví dụ:

function foo() {
    console.log(this);
}

// normal function call
foo(); // `this` will refer to `window`

// as object method
var obj = {bar: foo};
obj.bar(); // `this` will refer to `obj`

// as constructor function
new foo(); // `this` will refer to an object that inherits from `foo.prototype`

Để tìm hiểu thêm this, hãy xem tài liệu MDN .


Làm thế nào để tham khảo chính xác this

Sử dụng các chức năng mũi tên

ECMAScript 6 đã giới thiệu các hàm mũi tên , có thể được coi là các hàm lambda. Họ không có thisràng buộc riêng của họ . Thay vào đó, thisđược tra cứu trong phạm vi giống như một biến bình thường. Điều đó có nghĩa là bạn không cần phải gọi .bind. Đó không phải là hành vi đặc biệt duy nhất mà họ có, vui lòng tham khảo tài liệu MDN để biết thêm thông tin.

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', () => alert(this.data));
}

Không sử dụng this

Bạn thực sự không muốn truy cập thiscụ thể, nhưng đối tượng mà nó đề cập đến . Đó là lý do tại sao một giải pháp đơn giản là tạo một biến mới cũng tham chiếu đến đối tượng đó. Biến có thể có bất kỳ tên nào, nhưng những tên phổ biến là selfthat.

function MyConstructor(data, transport) {
    this.data = data;
    var self = this;
    transport.on('data', function() {
        alert(self.data);
    });
}

selflà một biến bình thường, nó tuân theo các quy tắc phạm vi từ vựng và có thể truy cập được bên trong lệnh gọi lại. Điều này cũng có lợi thế là bạn có thể truy cập thisgiá trị của chính lệnh gọi lại.

Tập hợp rõ ràng thiscủa cuộc gọi lại - phần 1

Có vẻ như bạn không kiểm soát được giá trị của thisvì giá trị của nó được đặt tự động, nhưng thực tế không phải vậy.

Mỗi hàm đều có phương thức .bind [docs] , phương thức này trả về một hàm mới có thisgiới hạn cho một giá trị. Hàm có hành vi giống hệt như hàm mà bạn đã gọi .bind, chỉ khác thislà do bạn thiết lập. Bất kể hàm đó được gọi như thế nào hoặc khi nào, thissẽ luôn tham chiếu đến giá trị được truyền vào.

function MyConstructor(data, transport) {
    this.data = data;
    var boundFunction = (function() { // parenthesis are not necessary
        alert(this.data);             // but might improve readability
    }).bind(this); // <- here we are calling `.bind()` 
    transport.on('data', boundFunction);
}

Trong trường hợp này, chúng tôi đang ràng buộc callback's thisvới giá trị của MyConstructor's this.

Lưu ý: Khi một ngữ cảnh ràng buộc cho jQuery, hãy sử dụng jQuery.proxy [docs] thay thế. Lý do để làm điều này là vì bạn không cần phải lưu trữ tham chiếu đến hàm khi hủy liên kết gọi lại sự kiện. jQuery xử lý nội bộ đó.

Đặt thiscủa cuộc gọi lại - phần 2

Một số hàm / phương thức chấp nhận lệnh gọi lại cũng chấp nhận giá trị mà lệnh gọi lại thisphải tham chiếu đến. Điều này về cơ bản giống như tự ràng buộc nó, nhưng hàm / phương thức sẽ làm điều đó cho bạn. Array#map [docs] là một phương pháp như vậy. Chữ ký của nó là:

array.map(callback[, thisArg])

Đối số đầu tiên là lệnh gọi lại và đối số thứ hai là giá trị thisnên tham chiếu đến. Đây là một ví dụ giả định:

var arr = [1, 2, 3];
var obj = {multiplier: 42};

var new_arr = arr.map(function(v) {
    return v * this.multiplier;
}, obj); // <- here we are passing `obj` as second argument

Lưu ý: Việc bạn có thể chuyển một giá trị cho thishay không thường được đề cập trong tài liệu của hàm / phương thức đó. Ví dụ: phương thức của jQuery [docs]$.ajax mô tả một tùy chọn được gọi là context:

Đối tượng này sẽ trở thành bối cảnh của tất cả các lệnh gọi lại liên quan đến Ajax.


Sự cố thường gặp: Sử dụng phương thức đối tượng làm trình xử lý gọi lại / sự kiện

Một biểu hiện phổ biến khác của vấn đề này là khi một phương thức đối tượng được sử dụng làm trình xử lý gọi lại / sự kiện. Các hàm là công dân hạng nhất trong JavaScript và thuật ngữ "phương thức" chỉ là một thuật ngữ thông tục cho một hàm là giá trị của một thuộc tính đối tượng. Nhưng hàm đó không có liên kết cụ thể đến đối tượng "chứa" của nó.

Hãy xem xét ví dụ sau:

function Foo() {
    this.data = 42,
    document.body.onclick = this.method;
}

Foo.prototype.method = function() {
    console.log(this.data);
};

Hàm this.methodđược chỉ định là trình xử lý sự kiện nhấp chuột, nhưng nếu document.bodyđược nhấp, giá trị được ghi lại sẽ là undefined, bởi vì bên trong trình xử lý sự kiện, thistham chiếu đến document.body, không phải trường hợp của Foo.
Như đã đề cập ở phần đầu, những gì thisđề cập đến phụ thuộc vào cách hàm được gọi , chứ không phải cách nó được định nghĩa .
Nếu mã giống như sau, có thể rõ ràng hơn là hàm không có tham chiếu ngầm đến đối tượng:

function method() {
    console.log(this.data);
}


function Foo() {
    this.data = 42,
    document.body.onclick = this.method;
}

Foo.prototype.method = method;

Giải pháp tương tự như đã đề cập ở trên: Nếu có, hãy sử dụng .bindđể liên kết rõ ràng thisvới một giá trị cụ thể

document.body.onclick = this.method.bind(this);

hoặc gọi hàm một cách rõ ràng là một "phương thức" của đối tượng, bằng cách sử dụng một hàm ẩn danh làm trình xử lý gọi lại / sự kiện và gán đối tượng ( this) cho một biến khác:

var self = this;
document.body.onclick = function() {
    self.method();
};

hoặc sử dụng hàm mũi tên:

document.body.onclick = () => this.method();
225 MohanDere Aug 13 2016 at 17:26

Dưới đây là một số cách để truy cập ngữ cảnh gốc bên trong ngữ cảnh con:

  1. Bạn có thể sử dụng bind()chức năng.
  2. Lưu trữ tham chiếu đến ngữ cảnh / điều này bên trong một biến khác (xem ví dụ bên dưới).
  3. Sử dụng các hàm Arrow của ES6 .
  4. Thay đổi mã / chức năng thiết kế / kiến ​​trúc - đối với điều này, bạn nên có lệnh trên các mẫu thiết kế trong javascript.

1. Sử dụng bind()chức năng

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', ( function () {
        alert(this.data);
    }).bind(this) );
}
// Mock transport object
var transport = {
    on: function(event, callback) {
        setTimeout(callback, 1000);
    }
};
// called as
var obj = new MyConstructor('foo', transport);

Nếu bạn đang sử dụng underscore.js- http://underscorejs.org/#bind

transport.on('data', _.bind(function () {
    alert(this.data);
}, this));

2 Lưu trữ tham chiếu đến ngữ cảnh / this bên trong một biến khác

function MyConstructor(data, transport) {
  var self = this;
  this.data = data;
  transport.on('data', function() {
    alert(self.data);
  });
}

3 Hàm mũi tên

function MyConstructor(data, transport) {
  this.data = data;
  transport.on('data', () => {
    alert(this.data);
  });
}
59 Guffa May 21 2014 at 07:11

Tất cả đều nằm trong cú pháp "kỳ diệu" khi gọi một phương thức:

object.property();

Khi bạn lấy thuộc tính từ đối tượng và gọi nó trong một lần, đối tượng sẽ là ngữ cảnh cho phương thức. Nếu bạn gọi cùng một phương thức, nhưng trong các bước riêng biệt, ngữ cảnh là phạm vi toàn cục (cửa sổ) thay thế:

var f = object.property;
f();

Khi bạn nhận được tham chiếu của một phương thức, nó không còn được gắn vào đối tượng nữa, nó chỉ là một tham chiếu đến một hàm thuần túy. Điều tương tự cũng xảy ra khi bạn lấy tham chiếu để sử dụng làm lệnh gọi lại:

this.saveNextLevelData(this.setAll);

Đó là nơi bạn sẽ liên kết ngữ cảnh với hàm:

this.saveNextLevelData(this.setAll.bind(this));

Nếu bạn đang sử dụng jQuery, bạn nên sử dụng $.proxyphương pháp này thay thế, vì bindnó không được hỗ trợ trong tất cả các trình duyệt:

this.saveNextLevelData($.proxy(this.setAll, this));
34 RobG Jun 01 2014 at 07:44

Rắc rối với "ngữ cảnh"

Thuật ngữ "ngữ cảnh" đôi khi được sử dụng để chỉ đối tượng được tham chiếu bởi điều này . Việc sử dụng nó là không phù hợp vì nó không phù hợp về mặt ngữ nghĩa hoặc kỹ thuật với cái này của ECMAScript .

"Ngữ cảnh" có nghĩa là hoàn cảnh xung quanh điều gì đó bổ sung ý nghĩa hoặc một số thông tin trước và sau cung cấp thêm ý nghĩa. Thuật ngữ "ngữ cảnh" được sử dụng trong ECMAScript để chỉ ngữ cảnh thực thi , là tất cả các tham số, phạm vi và điều này trong phạm vi của một số mã thực thi.

Điều này được thể hiện trong ECMA-262 phần 10.4.2 :

Đặt ThisBinding thành cùng giá trị với ThisBinding của ngữ cảnh thực thi cuộc gọi

chỉ rõ rằng đây là một phần của ngữ cảnh thực thi.

Bối cảnh thực thi cung cấp thông tin xung quanh bổ sung ý nghĩa cho mã đang được thực thi. Nó bao gồm nhiều thông tin hơn chỉ là Biên bản này .

Vì vậy, giá trị của đây không phải là "ngữ cảnh", nó chỉ là một phần của ngữ cảnh thực thi. Về cơ bản, nó là một biến cục bộ có thể được đặt bằng lệnh gọi tới bất kỳ đối tượng nào và ở chế độ nghiêm ngặt, thành bất kỳ giá trị nào.

32 Ashish Jan 30 2019 at 18:01

Bạn nên biết về Từ khoá "này".

Theo quan điểm của tôi, bạn có thể thực hiện "điều này" theo ba cách (Chức năng tự / Mũi tên / Phương pháp ràng buộc)

Một hàm của từ khóa này hoạt động hơi khác trong JavaScript so với các ngôn ngữ khác.

Nó cũng có một số khác biệt giữa chế độ nghiêm ngặt và chế độ không nghiêm ngặt.

Trong hầu hết các trường hợp, giá trị của điều này được xác định bởi cách một hàm được gọi.

Nó không thể được đặt bằng cách gán trong khi thực thi và nó có thể khác nhau mỗi khi hàm được gọi.

ES5 đã giới thiệu phương thức bind () để đặt giá trị của một hàm, bất kể nó được gọi như thế nào,

và ES2015 đã giới thiệu các hàm mũi tên không tự cung cấp ràng buộc này (nó giữ nguyên giá trị này của ngữ cảnh từ vựng đi kèm).

Phương pháp 1: Bản thân - Bản thân đang được sử dụng để duy trì tham chiếu đến bản gốc ngay cả khi bối cảnh đang thay đổi. Đó là một kỹ thuật thường được sử dụng trong các trình xử lý sự kiện (đặc biệt là trong các bao đóng).

Tham khảo : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

function MyConstructor(data, transport) {
    this.data = data;
    var self = this;
    transport.on('data', function () {
        alert(self.data);
    });
}

Phương pháp 2 : Hàm mũi tên - Biểu thức hàm mũi tên là một thay thế nhỏ gọn về mặt cú pháp cho biểu thức hàm thông thường,

mặc dù không có ràng buộc riêng với các từ khóa this, đối số, super hoặc new.target.

Biểu thức hàm mũi tên không phù hợp với tư cách là các phương thức và chúng không thể được sử dụng làm hàm tạo.

Tham khảo : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

  function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data',()=> {
        alert(this.data);
    });
}

Method3 : Bind- Phương thức bind () tạo ra một hàm mới,

khi được gọi, đặt từ khóa này thành giá trị được cung cấp,

với một chuỗi các đối số đã cho trước bất kỳ được cung cấp nào khi hàm mới được gọi.

Tham khảo: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind

  function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data',(function() {
        alert(this.data);
    }).bind(this);
26 AL-zami Aug 19 2017 at 00:58

Trước tiên, bạn cần phải hiểu rõ ràng scopevà hành vi của thistừ khóa trong ngữ cảnh scope.

this& scope:


there are two types of scope in javascript. They are :

   1) Global Scope

   2) Function Scope

Tóm lại, phạm vi toàn cục đề cập đến đối tượng cửa sổ, các biến được khai báo trong phạm vi toàn cục có thể truy cập từ bất cứ đâu, mặt khác phạm vi hàm nằm bên trong một hàm. Biến được khai báo bên trong một hàm không thể được truy cập từ thế giới bên ngoài một cách bình thường. thistừ khóa trong phạm vi toàn cục đề cập đến đối tượng cửa sổ. thishàm bên trong cũng thistham chiếu đến đối tượng cửa sổ Vì vậy sẽ luôn tham chiếu đến cửa sổ cho đến khi chúng ta tìm ra cách thao tác thisđể chỉ ra ngữ cảnh mà chúng ta chọn.

--------------------------------------------------------------------------------
-                                                                              -
-   Global Scope                                                               -
-   ( globally "this" refers to window object)                                 -     
-                                                                              -
-         function outer_function(callback){                                   -
-                                                                              -
-               // outer function scope                                        -
-               // inside outer function"this" keyword refers to window object -                                                                              -
-              callback() // "this" inside callback also refers window object  -

-         }                                                                    -
-                                                                              -
-         function callback_function(){                                        -
-                                                                              -
-                //  function to be passed as callback                         -
-                                                                              -
-                // here "THIS" refers to window object also                   -
-                                                                              -
-         }                                                                    -
-                                                                              -
-         outer_function(callback_function)                                    -
-         // invoke with callback                                              -
--------------------------------------------------------------------------------

Các cách khác nhau để thao tác thisbên trong các hàm gọi lại:

Ở đây tôi có một hàm khởi tạo được gọi là Person. Nó có một tính chất gọi namevà bốn phương pháp gọi là sayNameVersion1, sayNameVersion2, sayNameVersion3, sayNameVersion4. Tất cả bốn người trong số họ đều có một nhiệm vụ cụ thể, chấp nhận một lệnh gọi lại và gọi nó. Lệnh gọi lại có một nhiệm vụ cụ thể là ghi lại thuộc tính tên của một thể hiện của hàm khởi tạo Person.

function Person(name){

    this.name = name

    this.sayNameVersion1 = function(callback){
        callback.bind(this)()
    }
    this.sayNameVersion2 = function(callback){
        callback()
    }

    this.sayNameVersion3 = function(callback){
        callback.call(this)
    }

    this.sayNameVersion4 = function(callback){
        callback.apply(this)
    }

}

function niceCallback(){

    // function to be used as callback

    var parentObject = this

    console.log(parentObject)

}

Bây giờ chúng ta hãy tạo một thể hiện từ phương thức khởi tạo người và gọi các phiên bản khác nhau của phương thức sayNameVersionX(X tham chiếu đến 1,2,3,4) niceCallbackđể xem chúng ta có thể thao tác bao nhiêu cách để thao tác thisgọi lại bên trong để tham chiếu đến personcá thể.

var p1 = new Person('zami') // create an instance of Person constructor

trói buộc :

Những gì ràng buộc phải làm là tạo một hàm mới với thistừ khóa được đặt thành giá trị được cung cấp.

sayNameVersion1sayNameVersion2sử dụng ràng buộc để thao tác thisvới hàm gọi lại.

this.sayNameVersion1 = function(callback){
    callback.bind(this)()
}
this.sayNameVersion2 = function(callback){
    callback()
}

đầu tiên liên kết thisvới lệnh gọi lại bên trong chính phương thức và đối với lệnh gọi lại thứ hai được chuyển với đối tượng liên kết với nó.

p1.sayNameVersion1(niceCallback) // pass simply the callback and bind happens inside the sayNameVersion1 method

p1.sayNameVersion2(niceCallback.bind(p1)) // uses bind before passing callback

gọi :

Các first argumentcủa callphương pháp được sử dụng như thisbên trong hàm đó được gọi với callgắn liền với nó.

sayNameVersion3sử dụng callđể thao tác thisđể tham chiếu đến đối tượng người mà chúng tôi đã tạo, thay vì đối tượng cửa sổ.

this.sayNameVersion3 = function(callback){
    callback.call(this)
}

và nó được gọi như sau:

p1.sayNameVersion3(niceCallback)

ứng dụng :

Tương tự như call, đối số đầu tiên của applyđề cập đến đối tượng sẽ được chỉ định bằng thistừ khóa.

sayNameVersion4sử dụng applyđể thao tác thisđể chỉ đối tượng người

this.sayNameVersion4 = function(callback){
    callback.apply(this)
}

và nó được gọi như sau. Đơn giản là lệnh gọi lại được chuyển,

p1.sayNameVersion4(niceCallback)
20 DattaChanewad Nov 17 2017 at 21:32

Chúng tôi không thể ràng buộc điều này setTimeout(), vì nó luôn thực thi với đối tượng toàn cục (Cửa sổ) , nếu bạn muốn truy cập thisngữ cảnh trong hàm gọi lại thì bằng cách sử dụng bind()hàm gọi lại, chúng ta có thể đạt được như:

setTimeout(function(){
    this.methodName();
}.bind(this), 2000);
13 Code_Mode Feb 18 2019 at 16:10

Câu hỏi xoay quanh cách thistừ khóa hoạt động trong javascript. thishành xử khác nhau như bên dưới,

  1. Giá trị của thisthường được xác định bởi một ngữ cảnh thực thi hàm.
  2. Trong phạm vi toàn cục, thisđề cập đến đối tượng toàn cục ( windowđối tượng).
  3. Nếu chế độ nghiêm ngặt được bật cho bất kỳ chức năng nào thì giá trị của thissẽ undefinedgiống như trong chế độ nghiêm ngặt, đối tượng toàn cục tham chiếu undefinedthay cho windowđối tượng.
  4. Đối tượng đứng trước dấu chấm là đối tượng mà từ khóa này sẽ bị ràng buộc.
  5. Chúng ta có thể thiết lập giá trị của việc này một cách rõ ràng với call(), bind()apply()
  6. Khi newtừ khóa được sử dụng (một hàm tạo), từ khóa này được liên kết với đối tượng mới đang được tạo.
  7. Các hàm mũi tên không ràng buộc this - thay vào đó, thisđược ràng buộc theo từ vựng (tức là dựa trên ngữ cảnh ban đầu)

Như hầu hết các câu trả lời gợi ý, chúng ta có thể sử dụng hàm Arrow hoặc bind()Method hoặc Self var. Tôi sẽ trích dẫn một điểm về lambdas (Hàm mũi tên) từ Hướng dẫn kiểu JavaScript của Google

Thích sử dụng các hàm mũi tên trên f.bind (this) và đặc biệt là trên goog.bind (f, this). Tránh viết const self = this. Các hàm mũi tên đặc biệt hữu ích cho các lệnh gọi lại, đôi khi truyền các đối số bổ sung bất ngờ.

Google rõ ràng khuyên bạn nên sử dụng lambdas thay vì ràng buộc hoặc const self = this

Vì vậy, giải pháp tốt nhất sẽ là sử dụng lambdas như dưới đây,

function MyConstructor(data, transport) {
  this.data = data;
  transport.on('data', () => {
    alert(this.data);
  });
}

Người giới thiệu:

  1. https://medium.com/tech-tajawal/javascript-this-4-rules-7354abdb274c
  2. arrow-functions-vs-bind
8 skyboyer Sep 22 2018 at 20:38

Hiện tại, có thể có một cách tiếp cận khác nếu các lớp được sử dụng trong mã.

Với sự hỗ trợ của các trường lớp , bạn có thể thực hiện theo cách tiếp theo:

class someView {
    onSomeInputKeyUp = (event) => {
        console.log(this); // this refers to correct value
    // ....
    someInitMethod() {
        //...
        someInput.addEventListener('input', this.onSomeInputKeyUp)

Chắc chắn rằng đó là tất cả chức năng mũi tên cũ tốt để ràng buộc ngữ cảnh nhưng ở dạng này, nó trông rõ ràng hơn nhiều rằng ràng buộc rõ ràng.

Vì đó là Đề xuất Giai đoạn 3, bạn sẽ cần babel và plugin babel thích hợp để xử lý nó như hiện tại (08/2018).

5 AndreaPuddu Aug 28 2018 at 16:10

Một cách tiếp cận khác, là cách tiêu chuẩn kể từ khi DOM2 liên kết thisbên trong trình xử lý sự kiện, cho phép bạn luôn xóa trình nghe (trong số các lợi ích khác), là handleEvent(evt)phương pháp khỏi EventListenergiao diện:

var obj = {
  handleEvent(e) {
    // always true
    console.log(this === obj);
  }
};

document.body.addEventListener('click', obj);

Thông tin chi tiết về việc sử dụng handleEventcó thể được tìm thấy tại đây: https://medium.com/@WebReflection/dom-handleevent-a-cross-platform-standard-since-year-2000-5bf17287fd38

2 WillemvanderVeen May 05 2020 at 15:48

this trong JS:

Giá trị của thistrong JS được xác định 100% bởi cách một hàm được gọi chứ không phải cách nó được định nghĩa. Chúng ta có thể tương đối dễ dàng tìm thấy những giá trị của thiscác 'trái của dot quy tắc' :

  1. Khi hàm được tạo bằng từ khóa hàm, giá trị của thislà đối tượng bên trái dấu chấm của hàm được gọi là
  2. Nếu không có đối tượng nào còn lại của dấu chấm thì giá trị của thisbên trong một hàm thường là đối tượng toàn cục ( globaltrong nút, windowtrong trình duyệt). Tôi không khuyên bạn nên sử dụng thistừ khóa ở đây vì nó ít rõ ràng hơn là sử dụng một cái gì đó như thế window!
  3. Tồn tại một số cấu trúc nhất định như hàm mũi tên và hàm được tạo bằng cách sử dụng Function.prototype.bind()một hàm có thể cố định giá trị của this. Đây là những ngoại lệ của quy tắc nhưng thực sự hữu ích để sửa giá trị của this.

Ví dụ trong nodeJS

module.exports.data = 'module data';
// This outside a function in node refers to module.exports object
console.log(this);

const obj1 = {
    data: "obj1 data",
    met1: function () {
        console.log(this.data);
    },
    met2: () => {
        console.log(this.data);
    },
};

const obj2 = {
    data: "obj2 data",
    test1: function () {
        console.log(this.data);
    },
    test2: function () {
        console.log(this.data);
    }.bind(obj1),
    test3: obj1.met1,
    test4: obj1.met2,
};

obj2.test1();
obj2.test2();
obj2.test3();
obj2.test4();
obj1.met1.call(obj2);

Đầu ra:

Hãy để tôi hướng dẫn bạn qua từng kết quả đầu ra 1 (bỏ qua nhật ký đầu tiên bắt đầu từ nhật ký thứ hai):

  1. thisobj2do bên trái của quy tắc dấu chấm, chúng ta có thể thấy như thế nào test1được gọi là obj2.test1();. obj2là bên trái của dấu chấm và do đó thisgiá trị.
  2. Mặc dù obj2ở bên trái của dấu chấm, test2được liên kết với obj1thông qua bind()phương thức. Vậy thisgiá trị là obj1.
  3. obj2còn lại của dấu chấm từ chức năng được gọi là: obj2.test3(). Do đó obj2sẽ là giá trị của this.
  4. Trong trường hợp này: obj2.test4() obj2là bên trái của dấu chấm. Tuy nhiên, các hàm mũi tên không có thisràng buộc riêng . Do đó, nó sẽ liên kết với thisgiá trị của phạm vi bên ngoài là module.exportsmột đối tượng đã được ghi vào đầu.
  5. Chúng ta cũng có thể chỉ định giá trị của thisbằng cách sử dụng callhàm. Ở đây chúng ta có thể chuyển thisgiá trị mong muốn làm đối số, obj2trong trường hợp này là giá trị .
1 Md.TazbirUrRahmanBhuiyan Oct 12 2020 at 23:07

Tôi đã phải đối mặt với vấn đề với Ngxbiểu đồ đường thẳng xAxisTickFormattingchức năng được gọi là từ HTML như thế này: [xAxisTickFormatting]="xFormat". Tôi không thể truy cập biến thành phần của mình từ hàm đã khai báo. Giải pháp này đã giúp tôi giải quyết vấn đề để tìm ra chính xác điều này. Hy vọng điều này sẽ giúp các Ngxbiểu đồ đường, người dùng.

thay vì sử dụng hàm như thế này:

xFormat (value): string {
  return value.toString() + this.oneComponentVariable; //gives wrong result 
}

Dùng cái này:

 xFormat = (value) => {
   // console.log(this);
   // now you have access to your component variables
   return value + this.oneComponentVariable
 }