2016-08-12 22 views
12

Tôi đang học tiêu chuẩn ES6 vì vậy tôi bắt đầu từ một mã ví dụ rất cơ bản.Công việc xuất/nhập trong ES6 như thế nào?

file đầu tiên của tôi là Rectangle.js

class Rectangle { 
    perimeter(x, y) { 
    return (2 * (x + y)); 
    } 
    area(x, y) { 
    return (x * y); 
    } 
} 

export default class { Rectangle }; 

Và trong một tập tin solve-1.js, tôi có một số hàng nhập khẩu như thế này

import Rectangle from './Rectangle'; 

function solveRect(l, b) { 
    if (l < 0 || b < 0) { 
    console.log(`Rectangle dimensions should be greater than zero: l = ${l} and b = ${b}`); 
    } else { 
    console.log(Rectangle.area(l, b)); 
    } 
} 

solveRect(2, 4); 

Tôi đang sử dụng babel-nút để chạy chương trình này, tôi đã yêu cầu cài đặt trước, .babelrc chứa

{ 
    "presets": [ 
    "es2015", 
    "react", 
    "stage-2" 
    ], 
    "plugins": [] 
} 

Các báo cáo thông tin lỗi là

/Users/Kulbear/Desktop/NodeBear/Basic/solve-1.js:13 
    console.log(_Rectangle2.default.area(l, b)); 
            ^

TypeError: _Rectangle2.default.area is not a function 
    at solveRect (solve-1.js:7:27) 
    at Object.<anonymous> (solve-1.js:12:1) 
    at Module._compile (module.js:541:32) 
    at loader (/usr/local/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:148:5) 
    at Object.require.extensions.(anonymous function) [as .js] (/usr/local/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:158:7) 
    at Module.load (module.js:458:32) 
    at tryModuleLoad (module.js:417:12) 
    at Function.Module._load (module.js:409:3) 
    at Function.Module.runMain (module.js:575:10) 
    at /usr/local/lib/node_modules/babel-cli/lib/_babel-node.js:160:24 

Edit:

$ node --version 
> v6.3.1 
+0

Might hữu ích khi đọc một số tài liệu về các tính năng mới của ES6, ví dụ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes. –

Trả lời

17

tôi thấy hai vấn đề:

  1. dòng này:

    export default class { Rectangle }; 
    

    ... đang cố gắng tạo mới lớp nào đó có chứa Rectangle. Nó sẽ không biên dịch, nhưng bạn đã bao gồm Giai đoạn 2 trong số .babelrc của bạn và vì vậy Babel nghĩ rằng đó là một nỗ lực để tạo ra một field. Tôi nghĩ bạn có thể muốn:

    export default Rectangle; 
    
  2. Bạn không có Rectangle.area(l, b). Bạn đã xác định area làm phương thức Rectangletrường hợp, không phải là phương pháp tĩnh. Hoặc thay đổi nó vào một tĩnh:

    static area() { 
        // ... 
    } 
    

    hay khi bạn sử dụng nó, sử dụng một ví dụ

    var r = new Rectangle(); 
    r.area(/*...*/); 
    

    Từ mã này, bạn muốn static.

Vì vậy, tham gia hai điều này và đưa chúng lại với nhau (tôi đã perimeterstatic cũng):

Rectangle.js:

class Rectangle { 
    static perimeter(x, y) { 
    return (2 * (x + y)); 
    } 
    static area(x, y) { 
    return (x * y); 
    } 
} 

export default Rectangle; 

solve-1.js:

import Rectangle from './Rectangle'; 

function solveRect(l, b) { 
    if (l < 0 || b < 0) { 
    console.log(`Rectangle dimensions should be greater than zero: l = ${l} and b = ${b}`); 
    } else { 
    console.log(Rectangle.area(l, b)); 
    } 
} 
solveRect(2, 4); 

trình:

 
$ babel-node solve-1.js 
8 

Một vài ghi chú bên:

  1. Nếu bạn thích, bạn có thể kết hợp tờ khai xuất khẩu và lớp:

    export default class Rectangle { 
         // ...implementaton 
        } 
    

    Lưu ý rằng đó là một declaraion, vì vậy không giống như các mặt hàng xuất khẩu khác, nó không kết thúc bằng ; (handy reference; mặc dù bao gồm một là vô hại).

  2. Nếu Rectanglechỉstatic phương pháp, không có lý do gì để trở thành lớp học cả; chỉ cần sử dụng tên xuất khẩu chức năng tĩnh của bạn:

    export function perimeter { 
        // ... 
    } 
    export function area { 
        // ... 
    } 
    

    Sau đó, người nhập khẩu có thể sử dụng cú pháp nhập tên nếu họ chỉ muốn một trong những:

    import area from './Rectangle'; 
    

    ... và nếu họ muốn tất cả trong số họ, họ có thể sử dụng nhập không gian tên:

    import * as Rectangle from './Rectangle'; 
    

    và sau đó sử dụng Rectangle.area hoặc tương tự.

    Ví dụ: nó mang lại cho người dùng sự linh hoạt của mô-đun.

+0

Đọc lại tại thời điểm này, và nó thực sự là một câu trả lời phức tạp, cảm ơn! - – Kulbear

5

T.J. đã nói, dòng sau không thực sự có ý nghĩa:

export default class { Rectangle }; 

Nhưng nó là JS hợp lệ. Những gì bạn đang thực sự đang làm là xuất một số vô danh class có thuộc tính "Rectangle" và giá trị của thuộc tính này là hàm tạo cho số class Rectangle trước đây của bạn.

Vì vậy, khi bạn nhập ở trên bạn sẽ phải làm như sau để có nó hoạt động đúng:

import Rectangle from './Rectangle'; 

const rect1 = new Rectangle(); 
const rect2 = new rect1.Rectangle(); 
rect2.area(5,5); 

Tất nhiên điều này là không thực sự những gì bạn muốn làm.Những gì bạn thực sự muốn là:

export default Rectangle; 

Ngoài ra, có vẻ như bạn chỉ muốn một số phương pháp thay vì xây dựng cả lớp. Ít nhất trong ví dụ của bạn, bạn không tạo ra một thể hiện của đối tượng Rectangle.

Nếu đây là trường hợp tôi sẽ đề nghị bạn loại bỏ các lớp và làm điều gì đó như thế này:

export function perimeter (x, y) { 
    return (2 * (x + y)); 
} 
export function area(x, y) { 
    return (x * y); 
} 

Sau đó, bạn có thể làm như sau để nhập khẩu và sử dụng các phương pháp xác định:

import * as Rectangle from './Rectangle'; 
console.log(Rectangle.area(5,5)); 
+0

Vâng, nó sẽ có giá trị trong ES2017 (và hợp lệ cho OP, vì chúng đã bao gồm Giai đoạn 2). –

+0

Không bao giờ nói rằng nó không hợp lệ ES :) Tôi đã cố gắng giải thích những gì mã của mình thực sự làm. –

+1

Không, bạn nói là * hợp lệ *. Tôi đang nói đùa rằng nó * sẽ * hợp lệ trong ES2017 (và hợp lệ cho OP vì chúng đã bao gồm Giai đoạn 2 trong '.babelrc') của họ, nhưng không hợp lệ * bây giờ *. Xin lỗi nếu nó không đi. :-) –

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