require与imoprt的区别
require遵循的是commonjs规范,import遵循的是es6module规则。
- 区别1:require的过程是赋值过程,通过require引入基础数据类型时,属于复制该变量。通过require引入复杂数据类型时,数据浅拷贝该对象。
//基本类型导入示例代码如下:
// a.js
let count = 1
let setCount = () =>{
count++
}
setTimeout(() =>{
console.log('a', count)
}, 1000)
module.exports = {
count,
setCount
}
// b.js
let obj = require('./a.js')
obj.setCount()
console.log('b', obj.count)
//node b.js
//b 1
//a 2
//可以看出,count在b.js文件中复制了一份,
//setCount只改变了a.js中count值
//关于对象的导入示例代码如下:
// a.js
let obj = {
count: 1
}
let setCount = () =>{
obj.count++
}
setTimeout(() =>{
console.log('a', obj.count)
}, 1000)
module.exports = {
obj,
setCount
}
// b.js
let data = require('./a.js')
data.setCount()
console.log('b', data.obj.count)
//node b.js
//b 2
//a 2
//从以上可以看出,a.js和b.js实际上指向同一个obj对象
import的导入过程是解构过程,并且是强绑定的。
- 不管是基础(复杂)数据类型,都只是对该变量的动态只读引用。
- 动态在于一个模块中变量的变化会影响到另一个模块;只读在于从某个模块引入一个变量时,不允许修改该变量的值。对于复杂数据类型,可以添加属性和方法,但是不允许指向另一个内存空间。
这里要强调一点用import导入的数据被变量接收后,这些变量类似用const定义过,都是只读的,不允许重新赋值,引用类型可以增删修改属性。
代码如下:
//a1.js
let a = 100;
export {a};
//b1.js
import {a} from "./a1.js";
a = 200;
// 代码会报错
- 区别2、es6module引用基本类型是动态引用的,被引入文件的数据发生变化,会影响引入文件
//a1.js
let count = 1
function setcount(){
count ++
}
setTimeout(() => {
console.log('a', count)
}, 1000)
export {
count,
setcount
}
//b1.js
import {count,setcount} from "./a1.js";
setcount();
console.log(count);
// babel-node --presets env b1.js
// b 2
// a 2
- 区别3、require使用的位置比较随意,比方说可以在函数内部使用,而import只能在文件作用域最外层使用。否则会报错:
即使用在if判断语句中也会出错:
这点require就比较灵活了。 - 区别4,对于循环引用的处理:
require循环加载时,属于加载时执行。即脚本代码在require的时候,就会全部执行。一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。
import循环加载时,ES6模块是动态引用。只要两个模块之间存在某个引用,代码就能够执行,也就是可能会陷入死循环。
代码如下:
// b1.js
import {foo} from './a1.js';
export function bar() {
console.log('bar');
foo();
}
// a1.js
import {bar} from './b1.js';
export function foo() {
console.log('foo');
bar();
console.log('执行完毕');
}
foo();
// 上面代码就会陷入死循环
改成commonjs规范来写如下:
//b.js
var foo = require("./a.js");
function bar() {
console.log('bar');
foo();
}
module.exports= bar
//a.js
var bar = require("./b.js");
function foo() {
console.log('foo');
bar();
console.log('执行完毕');
}
module.exports = foo()
foo();
// 以上代码,不会陷入死循环,但是会导致a.js提前导出
- 区别5,require是一个函数,在使用时传入的参数可以动态计算,例如:
require(“./”+"a.js")这样使用不会报错,但是如果使用 import “./”+"a.js",就会出现问题。
网友评论