前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >require与imoprt的区别

require与imoprt的区别

作者头像
挥刀北上
发布2019-07-19 15:43:50
1.2K0
发布2019-07-19 15:43:50
举报
文章被收录于专栏:Node.js开发Node.js开发

在讨论require和import的区别之前,我们首先要了解的是,es6module的代码最终都会被打包工具转化为require才能实行,关于这俩的区别网上有大把的文章,但是都不是很系统,小编这里整合了一下,总结了一下这两者区别,require遵循的是commonjs规范,import遵循的是es6module规则。

区别1:require的过程是赋值过程,通过require引入基础数据类型时,属于复制该变量。通过require引入复杂数据类型时,数据浅拷贝该对象。

基本类型导入示例代码如下:

代码语言:javascript
复制
// 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值

关于对象的导入示例代码如下:

代码语言:javascript
复制
// 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对象

在b.js这种引入a.js导入对象obj,a.js在0.5秒后改变对象obj的count属性,b.j一秒后输出obj.count,obj.count也改变了,所以说明两个文件中的对象obj指向的是同一个内存地址。

import的导入过程是解构过程,并且是强绑定的。

1、不管是基础(复杂)数据类型,都只是对该变量的动态只读引用。

2、动态在于一个模块中变量的变化会影响到另一个模块;只读在于从某个模块引入一个变量时,不允许修改该变量的值。对于复杂数据类型,可以添加属性和方法,但是不允许指向另一个内存空间。

这里要强调一点用import导入的数据被变量接收后,这些变量类似用const定义过,都是只读的,不允许重新赋值,引用类型可以增删修改属性。

代码如下:

代码语言:javascript
复制
//a.js
let a  = 100;
export {a};
//b.js 
import {a} from "./a.js";
a = 200;

上面的代码会报错;

从上面的区别中可以看出,不论是require还是import导入的是引用类型的话,只要不对接收的变量重新赋值,使用方式是一样的,引用类型数据指向的是同一个内存地址。

但是基本类型的使用就不同了,使用require导入的基本类型等于是拷贝了一个新的值,而import因为是动态引用所以被引入文件中的基本类型数据发生变化,引入的文件中的数据也会发生变化,我们将第一份代码改成import的方式,代码如下:

代码语言:javascript
复制
//a.js

let count = 1
function setcount(){
    count ++
}
setTimeout(() => {
  console.log('a', count)
}, 1000)
export {
  count,
  setcount
}

//b.js
import {count,setcount} from "./m1.js";
setcount();
console.log(count);

// node b.js
// b 2
// a 2

通过执行结果我们可以看到es6module引用基本类型是动态引用的,被引入文件的数据发生变化,会影响引入文件。

区别2、require使用的位置比较随意,比方说可以在函数内部使用,而import只能在文件作用域最外层使用。否则会报错:

即使用在if判断语句中也会出错:

这点require就比较灵活了。

区别3,import最终会被转化为require,这里面需要注意的是:Imports are hoisted 这句话暂时没有找到对应的中文语句来翻译,啥意思呢?就是import在编译转化为require时,会被挪到文件的顶部执行,代码如下:

代码语言:javascript
复制
// a.js
global.log = (str) => console.log(str);
import './b';

// b.js
global.log('hello world');

由于 import 被提升最终转化为的代码如下:

代码语言:javascript
复制
'use strict';
global.log('hello world');
global.log = function (str) {
  return console.log(str);
};

所以会得到: log undefined。

关于 imports are hostied的解释在stackoverfllow于这样的解释:

Imports ARE hoisted! according to the spec of ModuleDeclarationInstantiation ALL the dependent Modules will be loaded before running any code. https://www.javascriptcn.com/read-29657.html

区别4,对于循环引用的处理:

require循环加载时,属于加载时执行。即脚本代码在require的时候,就会全部执行。一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。

import循环加载时,ES6模块是动态引用。只要两个模块之间存在某个引用,代码就能够执行,也就是可能会陷入死循环。

代码如下:

代码语言:javascript
复制
// b.js
import {foo} from './a.js';
export function bar() {
  console.log('bar');
    foo();
}

// a.js
import {bar} from './b.js';
export function foo() {
  console.log('foo');
  bar();
  console.log('执行完毕');
}
foo();

上面代码就会陷入死循环,执行结果如下:

改成commonjs规范来写如下:

代码语言:javascript
复制
//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(“/b”+"/a.js")这样使用不会报错,但是如果使用 import “/b”+"/a.js",就会出现问题。

以上便是require和imports的区别,可能总结的还不是很全面,如果你有什么问题或者建议,欢迎留言。

引用资料:

https://www.zhihu.com/question/56820346

http://www.sohu.com/a/139735984_495695

http://www.cnblogs.com/unclekeith/p/7679503.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nodejs全栈开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档