2015-06-28 30 views
20

Trong ES6, cả hai đều hợp pháp:phương pháp trong các đối tượng ES6: sử dụng chức năng mũi tên

var chopper = { 
    owner: 'Zed', 
    getOwner: function() { return this.owner; } 
}; 

và, như viết tắt:

var chopper = { 
    owner: 'Zed', 
    getOwner() { return this.owner; } 
} 

Có thể sử dụng các chức năng mũi tên mới cũng ? Trong cố gắng một cái gì đó giống như

var chopper = { 
    owner: 'John', 
    getOwner: => { return this.owner; } 
}; 

hoặc

var chopper = { 
    owner: 'John', 
    getOwner: => (this.owner) 
}; 

tôi nhận được một thông báo lỗi cho thấy rằng phương pháp này không có quyền truy cập vào this. Đây có phải chỉ là một vấn đề cú pháp, hoặc bạn không thể sử dụng các phương pháp đường ống mỡ bên trong các đối tượng ES6?

+5

Một trong những điểm lớn nhất của cú pháp hàm mới là nó xử lý 'điều này' khác nhau. Nó được định nghĩa bởi môi trường từ vựng trong đó hàm được tạo ra, có nghĩa là giá trị 'this' mà bạn tạo biến' chopper' sẽ là giá trị 'this' của hàm này. Nói cách khác, nó sẽ không tham chiếu đến đối tượng 'chopper'. –

+0

đã nhận được nó, có cách nào để viết lại chức năng này để nó đề cập đến 'chủ sở hữu' bên trong chopper? – fox

+1

Trong khi sử dụng cú pháp mũi tên chất béo? Chỉ khi bạn thay đổi giá trị 'this' này trước tiên bằng cách tạo đối tượng' chopper', sau đó thực hiện nhiệm vụ trong một hàm có 'this' trỏ đến đối tượng đó. Điều này có thể được thực hiện khá sạch sẽ với một hàm xây dựng. –

Trả lời

32

Các chức năng mũi tên không được thiết kế để sử dụng trong mọi tình huống chỉ đơn thuần là phiên bản ngắn hơn của các chức năng cũ. Chúng không nhằm thay thế cú pháp hàm bằng cách sử dụng từ khóa function. Trường hợp sử dụng phổ biến nhất cho các chức năng mũi tên là "lambdas" ngắn không xác định lại this, thường được sử dụng khi chuyển một hàm làm gọi lại cho một số hàm.

chức năng mũi tên không thể được sử dụng để viết các phương pháp đối tượng bởi vì, như bạn đã thấy, vì mũi tên chức năng đảm nhận this của bối cảnh chức năng giải nghĩa từ vựng kèm theo, các this trong một định nghĩa đối tượng có thể là từ cửa sổ hay cái gì khác:

var foo = { 
    bar:() => this.baz // this is window or something else 
} 

Trong trường hợp của bạn, muốn viết một phương thức trên một đối tượng, bạn chỉ cần sử dụng tiêu chuẩn function syntax hoặc "tên phương thức viết tắt" được giới thiệu trong ES6.

Đã có một số cuộc tranh luận về danh sách gửi thư es6 về một sự thay đổi về các chức năng mũi tên có cú pháp tương tự nhưng với cú pháp của riêng chúng this. Tuy nhiên, đề xuất này đã được nhận ít bởi vì đó chỉ là đường cú pháp, cho phép mọi người lưu một vài ký tự và không cung cấp chức năng mới nào so với cú pháp hàm hiện có. Xem chủ đề unbound arrow functions.

Một đề nghị trước đó là giảm số lượng đột quỵ bằng cách sử dụng "cơ quan ngắn gọn", cho phép bạn không phải viết return, như trong

var foo = { 
    function bar() this.baz 
        ^^^^^^^^ "concise body" 
} 

nhưng điều này đã bị từ chối vì lý do parseability.

+0

Nếu tôi đọc chính xác điều này, có vẻ như gợi ý rằng danh sách gửi thư loại trừ đường cú pháp, ngay cả khi nó sẽ dẫn đến tính đồng nhất/dễ đọc hơn của mã. Vì nó là viết tắt, nó là khó khăn hơn nhiều để sử dụng các chức năng mũi tên chất béo trong một ngữ cảnh OOP theo ES6 hơn, nói, theo coffeescript. – fox

+0

Như tôi đã hiểu, cú pháp đường ** được coi là một lý do hợp lệ để xem xét các phần mở rộng ngôn ngữ, nhưng khi bạn nói với ưu tiên thấp hơn - nói cách khác, thanh cao hơn cho các đề xuất như vậy. –

5

Trong dòng này getOwner: => (this.owner) nên là:

var chopper = { 
    owner: 'John', 
    getOwner:() => this.owner 
}; //here `this` refers to `window` object. 

Bạn sẽ phải khai báo this vào một chức năng:

var chopper = { 
    owner: 'John', 
    getOwner() { return this.owner } 
}; 

Hoặc:

var chopperFn = function(){ 
 

 
    this.setOwner = (name) => this.owner = name; 
 
    Object.assign(this,{ 
 
     owner: 'Jhon', 
 
     getOwner:() => this.owner, 
 
    }) 
 

 
} 
 

 
var chopper = new chopperFn(); 
 
console.log(chopper.getOwner()); 
 
chopper.setOwner('Spiderman'); 
 
console.log(chopper.getOwner());

+1

Tôi nhận được một lỗi ở đây: '" TypeError: Không thể đọc thuộc tính 'chủ sở hữu' của undefined \ n tại Object.chopper.getOwner' – fox

+0

Tôi thấy, nó là sử dụng đúng, tuy nhiên phương thức esta luôn trả về đối tượng cửa sổ. sẽ phải khai báo 'this' trong một hàm: –

+2

' this' không nhất thiết phải tham chiếu đến 'window'. Nó ám chỉ bất cứ giá trị hiện tại nào của' this' này nằm trong môi trường kèm theo, có thể hoặc không có thể là 'window "Có lẽ đó là ý của bạn. Chỉ muốn chắc chắn rằng anh ta hiểu nó không phải là một giá trị mặc định. –

1

Chức năng mũi tên bên trong này không phản ánh ngữ cảnh của đối tượng. Thay vào đó nó cung cấp cho bối cảnh mà phương thức đối tượng được gọi.

Kiểm tra điều này, Điều này cung cấp một số thông tin chi tiết về thời điểm sử dụng mũi tên và khi nào không. https://dmitripavlutin.com/when-not-to-use-arrow-functions-in-javascript/

Các vấn đề liên quan