2015-02-06 19 views
28

Tôi đã đọc ở một số nơi mà sự khác biệt chính là "this bị ràng buộc từ từ trong các chức năng mũi tên." Đó là tất cả tốt và tốt, nhưng tôi không thực sự biết điều đó có nghĩa là gì."Điều này" đề cập đến trong các chức năng mũi tên trong ES6 là gì?

Tôi biết điều đó có nghĩa là nó duy nhất trong giới hạn của niềng răng xác định cơ thể của hàm, nhưng tôi không thể nói cho bạn biết đầu ra của mã sau, bởi vì tôi không biết ý nghĩa của this. với chức năng mũi tên chất béo .... không có vẻ hữu ích.

var testFunction =() => { console.log(this) }; 
testFunction(); 
+3

Nó chỉ đơn giản nắm bắt được giá trị của 'this' từ phạm vi chứa, đối xử với nó như bất kỳ o có biến. – Barmar

+1

Nó chỉ là do đó bạn không cần phải làm kludge của 'var self = this;' và sau đó sử dụng 'self' trong hàm. – Barmar

+4

Trong trường hợp của bạn, không có ngữ cảnh kèm theo, hoặc đó là bối cảnh toàn cục, hoặc ngữ cảnh mô-đun, vì vậy 'this' là bất cứ điều gì trong trường hợp đó, rất có thể là null hoặc window. Nói cách khác, 'this' có giá trị giống như nếu bạn thêm' console.log (this) 'trước khi gán hàm. –

Trả lời

19

Arrow functions capture the this value of the enclosing context

function Person(){ 
    this.age = 0; 

    setInterval(() => { 
    this.age++; // |this| properly refers to the person object 
    }, 1000); 
} 

var p = new Person(); 

Vì vậy, để trực tiếp trả lời câu hỏi của bạn, this bên trong mũi tên chức năng của bạn sẽ có cùng giá trị như nó đã làm ngay trước mũi tên hàm được giao.

+3

@torazaburo phản ứng muộn màng - câu trả lời là nó phụ thuộc vào nơi mà đoạn mã trong câu hỏi ban đầu đã được đặt. Nếu nó ở cấp cao nhất, 'this' là đối tượng' window' nếu chúng ta đang ở trong một trình duyệt và 'module.exports' nếu chúng ta đang ở trong môi trường Node. Vấn đề là, chức năng mũi tên * không có hiệu lực * trên giá trị của 'this'. – Aerovistae

+2

Nhận xét từ @dave, ''this' bên trong chức năng mũi tên của bạn sẽ có cùng giá trị như trước khi chức năng mũi tên được gán' là thứ cuối cùng làm cho nó được nhấp cho tôi. – Kevin

1

Hy vọng chương trình mã này có thể cung cấp cho bạn ý tưởng rõ ràng hơn. Về cơ bản, 'this' trong chức năng mũi tên là phiên bản ngữ cảnh hiện tại của 'this'. Xem mã:

// 'this' in normal function & arrow function 
var this1 = { 
    number: 123, 
    logFunction: function() { console.log(this); }, 
    logArrow:() => console.log(this) 
}; 
this1.logFunction(); // Object { number: 123} 
this1.logArrow(); // Window 
5

Để cung cấp bức tranh lớn, tôi sẽ giải thích cả ràng buộc động và từ vựng.

động Tên Binding

this đề cập đến đối tượng phương pháp này được gọi vào. Đây là câu đọc thường xuyên trên SO. Nhưng nó vẫn chỉ là một cụm từ, khá trừu tượng. Có một mẫu mã tương ứng với câu này không?

Có có:

const o = { 
    m() { console.log(this) } 
} 

// the important patterns: applying methods 

o.m(); // logs o 
o["m"](); // logs o 

m là một phương pháp vì nó dựa trên this. o.m() hoặc o["m"]() có nghĩa là m được áp dụng cho o. Những mẫu này là bản dịch Javascript cho cụm từ nổi tiếng của chúng tôi.

Còn có một mẫu mã quan trọng là bạn nên chú ý đến:

"use strict"; 

const o = { 
    m() { console.log(this) } 
} 

// m is passed to f as a callback 
function f(m) { m() } 

// another important pattern: passing methods 

f(o.m); // logs undefined 
f(o["m"]); // logs undefined 

Nó rất giống với mô hình trước đó, chỉ có ngoặc đang thiếu. Nhưng hậu quả là đáng kể: Khi bạn vượt qua m đến hàm f, bạn kéo ra m đối tượng/ngữ cảnh của nó o. Nó được bật gốc ngay bây giờ và this là không có gì (chế độ nghiêm ngặt giả định).

từ vựng (hoặc tĩnh) Tên Binding

chức năng mũi tên không có riêng this/super/arguments họ ràng buộc. Họ thừa kế chúng từ phạm vi từ vựng mẹ:

const toString = Object.prototype.toString; 
 

 
const o = { 
 
    foo:() => console.log("window", toString.call(this)), 
 
     
 
    bar() { 
 
    const baz =() => console.log("o", toString.call(this)); 
 
    baz(); 
 
    } 
 
} 
 

 
o.foo() // logs window [object Window] 
 
o.bar() // logs o [object Object]

Ngoài phạm vi toàn cầu (Window trong các trình duyệt) chỉ có chức năng có thể tạo thành một phạm vi trong Javascript (và {} khối trong ES2015).Khi chức năng mũi tên o.foo được gọi là không có chức năng xung quanh mà từ đó baz có thể kế thừa this của nó. Do đó nó bắt giữ ràng buộc this của phạm vi toàn cầu được ràng buộc với đối tượng Window.

Khi baz được gọi bởi o.bar, mũi tên hàm được bao quanh bởi o.bar (o.bar tạo cha mẹ phạm vi từ vựng của nó) và có thể kế thừa o.bar 's this ràng buộc. o.bar được gọi là o và do đó this của nó được ràng buộc với o.

0

Bạn có thể cố gắng tìm hiểu nó bằng cách làm theo những cách dưới đây

// whatever here it is, function or fat arrow or literally object declare 
// in short, a pair of curly braces should be appeared here, eg: 
function f() { 
    // the 'this' here is the 'this' in fat arrow function below, they are 
    // bind together right here 
    // if 'this' is meaningful here, eg. this === awesomeObject is true 
    console.log(this) // [object awesomeObject] 
    let a = (...param) => { 
    // 'this is meaningful here too. 
    console.log(this) // [object awesomeObject] 
} 

để 'này' chất béo mũi tên chức năng không bị ràng buộc, có nghĩa là bạn không thể làm bất cứ điều gì ràng buộc để 'này' ở đây, .apply thắng 't, .call sẽ không, sẽ không. 'this' trong chức năng mũi tên chất béo bị ràng buộc khi bạn viết xuống văn bản mã trong trình soạn thảo văn bản. 'này' trong chức năng mũi tên chất béo có nghĩa đen là có ý nghĩa ở đây. Những gì mã của bạn viết ở đây trong trình soạn thảo văn bản là những gì ứng dụng của bạn chạy ở đó trong repl. Cái này 'bị ràng buộc trong arror chất béo sẽ không bao giờ thay đổi trừ khi bạn thay đổi nó trong trình soạn thảo văn bản. Xin lỗi vì hồ bơi của tôi bằng tiếng Anh ...

chức năng
1

mũi tên this được trỏ đến phụ huynh xung quanh trong Es6, có nghĩa là nó không phạm vi như chức năng ẩn danh trong ES5 ...

Đó là cách rất hữu ích để tránh gán var tự này được sử dụng rộng rãi trong ES5 ...

Nhìn vào ví dụ dưới đây, gán một hàm bên trong một đối tượng:

var checkThis = { 
    normalFunction: function() { console.log(this); }, 
    arrowFunction:() => console.log(this) 
}; 

checkThis.normalFunction(); //Object {} 
checkThis.arrowFunction(); //Window {external: Object, chrome: Object, document: document, tmpDebug: "", j: 0…} 
Các vấn đề liên quan