2015-10-16 19 views
19

trong es6 đó bạn có thể xác định một mô-đun chức năng như thế nàyES6 mặc xuất khẩu với nhiều chức năng đề cập đến nhau

export default { 
    foo() { console.log('foo') }, 
    bar() { console.log('bar') }, 
    baz() { foo(); bar() } 
} 

ở trên có vẻ là mã hợp lệ, nhưng nếu tôi gọi baz() nó ném một lỗi:

ReferenceError: foo is not defined

làm thế nào để bạn gọi foo từ chức năng khác? trong trường hợp này baz

Sửa

Dưới đây là đoạn code mà thực sự không hoạt động. Tôi đã đơn giản hóa mã do đó, nó chỉ là cốt lõi khi cần thiết

const tokenManager = { 
    revokeToken(headers) { 
    ... 
    }, 
    expireToken(headers) { 
    ... 
    }, 
    verifyToken(req, res, next) { 
    jwt.verify(... => { 
     if (err) { 
     expireToken(req.headers) 
     } 
    }) 
    } 
} 

export default tokenManager 

và lỗi là

expireToken(req.headers); 
     ^
ReferenceError: expireToken is not defined 

Chỉnh sửa 2

Tôi chỉ cố gắng thêm tokenManager trước expireToken và cuối cùng làm việc

+1

Xem câu trả lời của tôi hoặc @ pawel. Để khắc phục, thay thế 'expireToken (req.headers)' bằng 'tokenManager.expireToken (req.headers)' hoặc bằng 'this.expireToken (req.headers)'. – skozin

Trả lời

38

Các export default {...} xây dựng chỉ là một phím tắt cho một cái gì đó như thế này:

const funcs = { 
    foo() { console.log('foo') }, 
    bar() { console.log('bar') }, 
    baz() { foo(); bar() } 
} 

export default funcs 

Nó phải trở nên rõ ràng bây giờ mà không có foo, bar hoặc baz chức năng trong phạm vi của mô-đun. Nhưng có một đối tượng có tên là funcs (mặc dù trong thực tế nó không có tên) chứa các hàm này làm các thuộc tính của nó và sẽ trở thành xuất khẩu mặc định của mô-đun.

Vì vậy, để sửa chữa mã của bạn, tái viết nó mà không sử dụng các phím tắt và tham khảo foobar như tính chất của funcs:

const funcs = { 
    foo() { console.log('foo') }, 
    bar() { console.log('bar') }, 
    baz() { funcs.foo(); funcs.bar() } // here is the fix 
} 

export default funcs 

Một lựa chọn khác là sử dụng this từ khóa để tham khảo funcs đối tượng mà không cần phải tuyên bố rõ ràng, as @pawel has pointed out.

Một tùy chọn khác (và tùy chọn tôi thường thích) là khai báo các chức năng này trong phạm vi mô-đun. Điều này cho phép để tham khảo trực tiếp với họ:

function foo() { console.log('foo') } 
function bar() { console.log('bar') } 
function baz() { foo(); bar() } 

export default {foo, bar, baz} 

Và nếu bạn muốn sự tiện lợi của xuất khẩu mặc định khả năng nhập các mục riêng biệt, bạn cũng có thể xuất khẩu tất cả các chức năng riêng lẻ:

// util.js 

export function foo() { console.log('foo') } 
export function bar() { console.log('bar') } 
export function baz() { foo(); bar() } 

export default {foo, bar, baz} 

// a.js, using default export 

import util from './util' 
util.foo() 

// b.js, using named exports 

import {bar} from './util' 
bar() 

Hoặc, như @loganfsmyth được đề xuất, bạn có thể làm mà không xuất mặc định và chỉ sử dụng import * as util from './util' để có được tất cả các tên được xuất trong một đối tượng.

+0

Tôi đã cố gắng này, nhưng không thể làm cho nó hoạt động. Tôi đã chỉnh sửa câu hỏi bằng mã thực. Bạn có thấy điều gì sai ở đây không? – chrs

+0

@chrs, xem nhận xét của tôi dưới câu hỏi của bạn. Bạn cần thay 'expireToken' bằng' tokenManager.expireToken'. – skozin

+0

Tôi đã cấp cho bạn sự chấp nhận vì bạn là người đầu tiên trả lời. Các câu trả lời khác cũng tốt, nhưng kể từ khi bạn là người đầu tiên bạn kiếm được nó :) – chrs

7

tl; dr: baz() { this.foo(); this.bar() }

Trong ES2015 cấu trúc này:

var obj = { 
    foo() { console.log('foo') } 
} 

bằng mã ES5 này:

var obj = { 
    foo : function foo() { console.log('foo') } 
} 

exports.default = {} cũng giống như việc tạo ra một đối tượng, xuất khẩu mặc định của bạn dịch sang mã ES5 như thế này:

exports['default'] = { 
    foo: function foo() { 
     console.log('foo'); 
    }, 
    bar: function bar() { 
     console.log('bar'); 
    }, 
    baz: function baz() { 
     foo();bar(); 
    } 
}; 

bây giờ, điều đó là hiển nhiên (tôi hy vọng) rằng baz cố gắng gọi foo một d bar được định nghĩa ở đâu đó trong phạm vi bên ngoài, không xác định. Nhưng this.foothis.bar sẽ giải quyết các khóa được xác định trong đối tượng exports['default']. Vì vậy, việc xuất mặc định tham chiếu các phương thức riêng của nó sẽ trông giống như sau:

export default { 
    foo() { console.log('foo') }, 
    bar() { console.log('bar') }, 
    baz() { this.foo(); this.bar() } 
} 

Xem babel repl transpiled code.

+0

Cảm ơn bạn đã trả lời! Tôi đã đi với giải pháp của sam mặc dù :) 1 lên – chrs

13

Một cách khác là thay đổi mô-đun của bạn. Nói chung, nếu bạn đang xuất một đối tượng có một loạt các hàm trên nó, sẽ dễ dàng hơn để xuất một loạt các hàm được đặt tên, ví dụ:

export function foo() { console.log('foo') }, 
export function bar() { console.log('bar') }, 
export function baz() { foo(); bar() } 

Trong trường hợp này bạn đang xuất khẩu tất cả các chức năng với những cái tên, vì vậy bạn có thể làm

import * as fns from './foo'; 

để có được một đối tượng với các thuộc tính cho mỗi chức năng thay vì nhập khẩu bạn muốn sử dụng cho bạn ví dụ đầu tiên:

import fns from './foo'; 
+1

Điều này dứt khoát là giải pháp vượt trội. Sử dụng xuất khẩu được đặt tên thay vì các đối tượng mặc định. – Bergi

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