最近在学习es6语法,想着chrome应该已经支持,于是想本地写写一测试代码,网上找es6相关的文章都是使用bable来转换的,但我只是本地测试一下,不是在正式环境上使用,不想再安装一堆东西.于是首先就想先试试模块的用法:
//test.js
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `(${this.x}, ${this.y})`;
}
}
export default Point;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<canvas id="test"></canvas>
</body>
<script>
import t from './test.js';
//export default ttt;
let x = 1;//t(1, 2);
console.log(x);
console.log(t);
let xx = new t(100, 500);
console.log(xx.toString());
</script>
</html>
代码很简单,可一运行就出错:
Uncaught SyntaxError: Unexpected identifier
查了一下出错的地方就是 import t from ‘./test.js’;
心想,不太可能啊,按道理chrome应该已经支持了,于是网上查了下兼容性,我的chrome是当前最前66的,除了前两项特性不支持,其他的都支持的,那应该可以执行才对.我又注释了Import这句和后面使用的语句:
<script>
//import t from './test.js';
//export default ttt;
let x = 1;//t(1, 2);
console.log(x);
//console.log(t);
//let xx = new t(100, 500);
//console.log(xx.toString());
</script>
发现这样是可以执行的,let是es6语法,说明可以支持这个特性,难道是不支持模块化?后面搞了半天查了下其实chrome61已经支持模块化,有网上的人说原因是使用模块化时script标签要加上 type=”module”
<script type="module">
import t from './test.js';
//export default ttt;
let x = 1;//t(1, 2);
console.log(x);
console.log(t);
let xx = new t(100, 500);
console.log(xx.toString());
</script>
以为这样就可以,但执行时出现
test.html:1 Access to Script at 'file:///home/fengzhiping/work/js/test/test.js' from origin 'null' has been blocked by CORS policy: Invalid response. Origin 'null' is therefore not allowed access.
这不是js跨域的意思吗,后来查了下果然是使用模块不能跨域:
https://blog.cloud66.com/an-overview-of-es6-modules-in-javascript/
CORS — Module scripts are requested with CORS and should make use of valid CORS headers e.g. Access-Control-Allow-Origin: *.
Use root relative paths to import modules — import {foo} from '/utils/bar.js'; works. import {foo} from 'utils/bar.js'; doesn't work.
Strict mode by default — ES6 modules run in strict mode (no 'use strict' is required).
The top level value of this is undefined — not the window object.
variables are local to the module — unless specifically exported.
Deferred by default — modules are non blocking and execute as defer scripts.
不能跨域?本地不是同一域名吗,想起来,这是本地路径不是本地服务器,于是安装anywhere执行在当前目录下再访问test.html就可以正常了!!!
好了,接下来简单讲讲export,import用法,通常export函数,变量,类都可以,如:
//export用法
export class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `(${this.x}, ${this.y})`;
}
}
export function hi() {
console.log('hi');
}
export const gloable = 11;
//import用法
import {Point, hi, gloable} from './test.js';
console.log(t);
let xx = new Point(100, 500);
console.log(xx.toString());
hi();
console.log(gloable)
import时要用{}括起来,里面的名称需要跟export时的名称一样,如果想不一样,可以export hi as hiFun来取个别名.
export直接导出需要知道里面有哪些导出的模块,如果不想了解里面导出模块的名称,则可用export default如:
export default class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `(${this.x}, ${this.y})`;
}
}
export function hi() {
console.log('hi');
}
export const gloable = 11;
//使用时,t名称可以随便取
import t from './test.js';
let xx = new t(100, 500);
console.log(xx.toString());
console.log(gloable)
import default的模块的名称可以随便取,实际上这种方法就是导出了个叫default的名称,如果用console.log(t)可以发现其实就是导出的class那一段代码,注意此时export的hi函数和变量gloable对外是看不见的,从log上看也可以知道,如果想在外面也能使用可以跟export一样:
import t, {hi, gloable} from './test.js';
let x = 1;//t(1, 2);
console.log(x);
console.log(t);
let xx = new t(100, 500);
console.log(xx.toString());
hi();
console.log(gloable)
此时导出的模块都能使用,只是非default的函数或变量也要里面外面名称一致!