Giá trị của từ khóa `this` của hàm được trả về từ một getter


15

Tôi tìm thấy một giá trị bất ngờ của từ khóa này trong ví dụ sau:

let x = {
    z : 10 ,
    get func1() {
        return function(v) {
            console.log(this === v);
        }
    }
}


x.func1(x)

Giá trị của này từ khóa là đối tượng x là nếu nó được thực hiện từ đối tượng đó, tôi hy vọng chỉ có chức năng getnày từ khóa tương đương với các đối tượng gọi x

ví dụ này cho chúng ta thấy sự khác biệt

let x = {
    func2() {
        return function(v) {
            console.log(this === v);
        }
    }
}

x.func2()(x);

Trong cả hai ví dụ func1 là hàm getter và func2 là một phương thức của đối tượng, được thực thi từ đối tượng x và sau đó hàm trả về sẽ được thực thi. Vậy tại sao giá trị này trong ví dụ đầu tiên không bằng đối tượng toàn cầu thay vì đối tượng x .


3
Thực sự, câu hỏi thực sự thú vị. Tôi chưa bao giờ mặc dù nếp nhăn này trước đây.
TJ Crowder

1
" như thể nó được thực thi từ đối tượng đó " - nhưng nó được thực thi trên đối tượng đó, ngay tại đó : x.func1().
Bergi

Câu trả lời:


13

Đó là một câu hỏi rất thú vị.

Đó là bởi vì chức năng đang được gọi ngay lập tức trên kết quả của việc truy cập thuộc tính. Vì vậy, những điều này là tương đương về cơ bản:

let x = {
    get func1() {
        return function(v) {
            console.log(this === v);
        };
    },
    func2(v) {
        console.log(this === v);
    }
};

x.func1(x);
x.func2(x);

Trong cả hai trường hợp:

  1. Giá trị của thuộc tính được đọc, dẫn đến tham chiếu hàm.
  2. Hàm đó được thực thi như một phần của cùng một biểu thức truy cập thuộc tính.

Thực tế đó func1là một thuộc tính truy cập và func2là một thuộc tính dữ liệu không thành vấn đề. Đó là cách giá trị kết quả từ việc đọc tài sản được sử dụng là vấn đề quan trọng.


1
Tôi nghĩ rằng toàn bộ biểu thức sẽ được ước tính cho đối tượng hàm và sau đó được thực thi. Cảm ơn đã nhận nó
Kirollos Nasr

1
@KirollosNasr Đúng vậy, nhưng trong biểu thức, x.func1nó giữ tham chiếu xlàm bối cảnh cho cuộc gọi tiếp theo, ngược lại với x.func2()(từ câu hỏi của bạn) cũng đánh giá một chức năng nhưng không phải là biểu thức truy cập thành viên.
Bergi

1
@Bergi - Tôi nghĩ bạn có ý x.func2()(x);gì?
TJ Crowder

1
@TJCrowder Vâng, tôi đề cập đến các biểu thức bên trong x.func1(x)x.func2()(x)
Bergi

1
@Bergi yeah nó có một phần khó khăn. Nhưng bây giờ thì rõ ràng hơn nhờ TJ Crowder và bạn
Kirollos Nasr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.