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

1524
Felix Kling 2013-11-29 20:13.

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?

12 answers

1910
Felix Kling 2013-11-29 20: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
Mohan Dere 2016-08-14 00: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 2014-05-21 14: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 2014-06-01 14: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 2019-01-31 01: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 2017-08-19 07: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
Datta Chanewad 2017-11-18 04: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 2019-02-18 23: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 2018-09-23 03: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
Andrea Puddu 2018-08-28 23: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
Willem van der Veen 2020-05-05 22: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

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
 }

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Xem đoạn giới thiệu cho bộ phim chuyển thể đầy khói lửa, có sự góp mặt của ngôi sao Edward Norton từ phim Motherless Brooklyn của Jonathan Lethem

Xem đoạn giới thiệu cho bộ phim chuyển thể đầy khói lửa, có sự góp mặt của ngôi sao Edward Norton từ phim Motherless Brooklyn của Jonathan Lethem

Edward Norton đã muốn đưa cuốn tiểu thuyết Motherless Brooklyn của Jonathan Lethem's Joycean 1999 lên màn ảnh kể từ khi nó được xuất bản. Bây giờ, 20 năm sau, một đoạn giới thiệu đã xuất hiện cho câu chuyện sôi nổi, đưa câu chuyện của Lethem trở lại những năm 1950 với rất nhiều gương mặt quen thuộc.

Cách dễ dàng chọn không tham gia trọng tài ràng buộc thẻ Apple

Cách dễ dàng chọn không tham gia trọng tài ràng buộc thẻ Apple

Có thích thú khi sử dụng Thẻ Apple mới của bạn không? Trước khi bạn bắt đầu chi tiêu, có một nhiệm vụ bổ sung cần xem xét: chọn không tham gia trọng tài ràng buộc. Bạn sẽ phát hiện ra các điều khoản trọng tài ràng buộc trong nhiều thỏa thuận tài chính vì nó giúp ngăn các ngân hàng và đối tác kinh doanh của họ không phải ra tòa.

Những người chơi Fortnite World Cup không ghi bàn có cảm giác hài hước về điều đó

Những người chơi Fortnite World Cup không ghi bàn có cảm giác hài hước về điều đó

Điểm số tại vòng chung kết Fortnite World Cup Solo hôm nay là rất lớn, với người chiến thắng Bugha ghi được nhiều hơn 26 điểm so với người về thứ hai là Psalm. Nhưng không phải ai cũng có thể giành chiến thắng: Bốn cầu thủ ra về với 0 điểm, nhưng — ít nhất là trên Twitter — họ là những người thể thao tốt về điều đó.

Báo cáo: Cánh cửa tuyển sinh có thể đã mở cho các ứng viên UCLA có mối quan hệ có ảnh hưởng

Báo cáo: Cánh cửa tuyển sinh có thể đã mở cho các ứng viên UCLA có mối quan hệ có ảnh hưởng

Huấn luyện viên trưởng của bộ môn thể dục dụng cụ UCLA Valorie Kondos-Field theo dõi Katelyn Ohashi thi đấu thăng bằng trong trận gặp Stanford tại Pauley Pavilion vào ngày 10 tháng 3 năm 2019 ở Los Angeles, California. Vụ bê bối gian lận tuyển sinh đại học tiết lộ các chi tiết của một quá trình chính thức hóa để đưa những đứa trẻ thất bại của các gia đình giàu có và nổi tiếng vào các trường đại học đáng tin cậy và danh tiếng, sử dụng một "cửa phụ" đắt tiền cho các bậc cha mẹ mà sự giàu có của họ khiến họ không có cơ hội. chỉ cần tài trợ cho một cánh mới trong khuôn viên trường.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Tầm nhìn đám mây phi tập trung của DFINITY Blockchain

Lưu ý của người biên tập: Bạn đang xem tài liệu lỗi thời từ blog DFINITY đang được bảo quản cho mục đích lưu trữ.

Tầm nhìn đám mây phi tập trung của DFINITY Blockchain

Bài đăng này khám phá tầm nhìn về đám mây phi tập trung của nhóm DFINITY và cách nó liên quan đến các nhà cung cấp blockchain truyền thống và đám mây hiện có như Amazon Web Services. Các minh chứng về công nghệ DFINITY được áp dụng bởi một mạng lưới quy mô lớn sẽ được thực hiện vào mùa thu năm 2017, sau đó sẽ được gây quỹ Chính cho quỹ hỗ trợ phi lợi nhuận, với mạng “đám mây mở” dự kiến ​​sẽ ra mắt vào đầu mùa hè năm 2018 .

Language