@octopus
2020-08-06T21:50:55.000000Z
字数 15119
阅读 1089
es6
进度:2.18-2.26_52studyit.com
var a = 1
b = 2
window.c = 3
let d = 4
const e = 4
变量 a 是全局变量,全局变量不可被删除,所以 delete a
时返回 false。可以通过 window 属性去访问
b 是 window 对象的属性,因为 windows对象全局可访问,所以 b也像全局变量一样可以被访问,但其实是属性,可被删除。
c 也是 window 对象的属性
d 是块级作用域变量,不可作为属性访问,不存在变量提升,不能被重新定义
e 是常量,具有 let的所有特点,且不能被修改,初始化时必须赋值。
// 例一
function test(){
var a = 1
if(a===1){
var b = 2
}
console.log(a+b) // 3
}
因为变量提升,上述代码实际被编译成:
function test(){
var a = 1
var b
if(a===1){
b = 2
}
console.log(a+b) // 3
}
所以最后能取到b,打印出 a+b 的值。
// 例二
function test(){
var a = 1
if(a===1){
let b = 2
}
console.log(a+b) // b is not defined
}
let 声名的变量是块级作用域,仅在 {}中生效,不存在变量提升,所以外层获取不到 b
// 例三
const b
b = 1 // Missing initializer in const declaration
常量在初始化时必须赋值
数组遍历的n种方式
//1
var arr = [1,2,3,4]
for(let i = 0; i<arr.length ; i++){
if(arr[i]===2){
continue
}
console.log(arr[i])
}
//2
var arr = [1,2,3,4]
arr.forEach(function (item) { // 此方法不支持 continue 与 break,只能完全遍历
console.log(item)
})
//3
var arr = [1,2,3,4]
arr.every(function (item) {
if(item !== 2){
console.log(item)
}
return true // 只有 return true 才能继续遍历
})
//4
var arr = [1,2,3,4]
for(let index in arr){
if(arr[index]===2){
continue
}
console.log(arr[index]);
}
//5
var arr = [1,2,3,4]
for(let item of arr){
console.log(item)
}
坑1:for in 不仅能打印数组值,还能打印属性。
for in 不是为数组准备的遍历功能,是为遍历对象而生,因为数组是对象,所以也可以用 for in 遍历。
数组是对象,所以也可以为它加属性:
var arr = [1,2,3,4]
arr.a = 8 // 加上自定义属性 a
for(let index in arr){
console.log(index, arr[index]);
}
输出:
0 1
1 2
2 3
3 4
a 8
坑2:for(let index in arr) 中的 index 是字符串类型
var arr = [1,2,3,4]
for(let index in arr){
if(index === 1){
continue
}
console.log(arr[index]);
}
输出:1,2,3,4
var arr = [1,2,3,4]
for(let index in arr){
if(index*1 === 1){ // *1强制转化为数字后即可
continue
}
console.log(arr[index]);
}
for of
es6及其以后可以自定义可遍历结构,也就是不止数组是可遍历对象,这时就不能用 for、forEach、every、for in等。
for of 就是为包括自定义的可遍历对象而生的
{0:"a",1:"b",length:2}
{length:5} // 可以理解为5个索引元素的值都是空
es5: [].slice.call(arrayLike)
es6: Array.from(arrayLike, mapFunc, thisArg)
集合/nodeList 都是伪数组,满足上述两种特性,看起来像数组但用不了数组的api
// 获取页面中所有的 img,返回一个 modeList
document.querySelectorAll("img")
NodeList [img]length: 10: imgalt: ""src: "http://localhost:8080/es2019.jpg"...
// 转换为数组
es5:
let imgs = [].slice.call(document.querySelectorAll("img"))
es6:
let imgs = Array.from(document.querySelectorAll("img"))
es5的老办法:
let arr = Array(n);
for(let i = 0; i<arr.length; i++){
arr[i] = 1
}
es6:
let arr = Array.from({length:n}, function () {return 1})
let arr = Array(n).fill(1)
es5:
var arr = Array()
var arr = []
es6:
let arr = Array.of(1,2); // [1,2]
let arr = Array(5).fill(1)
Array(7); // [ , , , , , , ]
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array(1, 2, 3); // [1, 2, 3]
可以填充数组,也可以批量改变数组的值。
// 填充数组
let arr = Array(5).fill(1)
// 批量改变数组值
let arr = [1,2,3,4,5,6]
let arr2 = arr.fill(8,1,3) // 将第1-3(包含头不包含尾)的元素值改成8
console.log(arr2) // [1, 8, 8, 4, 5, 6]
es5:
// 将 return true 的所有元素以数组格式返回,缺点是,如果只想知道是否存在一个元素,filter找到后依然会遍历所有元素,这并不高效
Array.filter(function(){})
es6:
// 将 return true 的第一个值返回,关注的是有或没有,找到了就返回值,没找到就返回undefined
Array.find(function(){})
// 返回第一个 return true 的元素位置
Array.findIndex(function(){})
举个例子:
// filter
let arr = [1,2,3,4,5,4]
let find = arr.filter(function (item) {
return item === 4
})
console.log(find) // [4, 4]
// find
let arr = [1,2,3,4,5,4]
let find = arr.find(function (item) {
return item === 4
})
console.log(find) // 4
// findIndex
let arr = [1,2,3,4,5,4]
let find = arr.findIndex(function (item) {
return item === 4
})
console.log(find) // 3
es5:
let Animal = function (type) {
this.type = type
this.eat = function () {
console.log(this.type+"正在吃...")
}
}
let dog = new Animal("dog");
let cat = new Animal("cat");
1. 隐式地创建一个空对象 obj = {}
2. Animal.call(obj,type), 将 this 指向的作用域变成 obj,并初始化,则 obj 有了 Animal 初始化后的的所有属性和方法。(值拷贝)
3. obj.__proto__= Animal.prototype,将原型链指向函数,存的是引用地址。(prototype属性,可以返回对象的 原型对象 的引用。)
4. 返回obj对象
这就导致,每生成一个类,都完全复制了一份父类,使占用的空间变的很大,且 eat 本是想作为一个父类的公共方法,new 以后却变成了每个子类的"私有"方法。
对象就像是一个封装好的盲盒,盲盒里有图纸,和一张说明。图纸谁拿到了都可以修改,但是说明只有盲盒本盒才有权改(盲盒可读可写,其他人只读)。
A = function(){ // 这是盲盒 A
this.type = "flower" // 图纸,可以生产花
}
A.prototype // 这是盲盒 A 里的说明
A.prototype.warning = "不可以生产蓝花" // 在说明里新增一条注意事项
说明上都记录着什么呢?
console.log(A.prototype)
// 结果:
warning: "不可以生产蓝花"
constructor: ƒ ()
length: 0
name: "A"
arguments: null
caller: null
prototype: {constructor: ƒ}
__proto__: ƒ ()
[[FunctionLocation]]: VM64:1
[[Scopes]]: Scopes[2]
__proto__:
constructor: ƒ Object()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
hasOwnProperty: ƒ hasOwnProperty()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toString: ƒ toString()
valueOf: ƒ valueOf()
toLocaleString: ƒ toLocaleString()
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
记录着涂鸦(warning),盲盒本身(指针指向外层)(constructor) ,盲盒来源的说明的地址(__proto__)
有了盲盒,就有了可以使用盲盒生产东西的工厂,开工厂就一个条件,要有使用的盲盒说明的地址。
现在有一个工厂 a 想用图纸 A 生产花,生产红色的花,于是 a 打开了盲盒,复印并修改了盲盒图纸,同时按照要求挂上了使用的盲盒说明的地址。
let a = new A()
a.type = "red flower"
consloe.log(a);
// 打印结果:
type: "red flower" // 工厂生产的东西
__proto__: // 盲盒的说明
warning: "不允许狗进入"
constructor: ƒ () // 盲盒本身
length: 0
name: "A"
arguments: null
caller: null
prototype: {warning: "不允许狗进入", constructor: ƒ} // 盲盒的说明
__proto__: ƒ ()
[[FunctionLocation]]: test.js:1
[[Scopes]]: Scopes[2]
__proto__: // 盲盒的来源的说明
...
所以假如 a 不禁想修改图纸,还想修改说明上的涂鸦,让所有工厂都改变这个涂鸦,就要联系盲盒本盒:
a.constructor.prototype.warning = "允许狗进入"
因为当获取一个属性,而本身找不到时,就会自动去来源处寻找,所以 a 本身并没有constructor方法,程序会自动去 __proto__ 中找到,父级依然没有的话,会一直向上找。
了解了原型链后,该如何解决公共方法的问题?—— 将共有属性和方法,放在原型链中,实例化时不会拷贝,调用时会顺着 __proto__ 指向的地址去找
let Animal = function (type) {
this.type = type
}
Animal.prototype.eat = function () {
console.log(this.type+"正在吃...")
}
let dog = Animal("dog");
let cat = Animal("cat");
es6:
class A {
constructor (type) {
this.type = type
}
eat(){
console.log(this.type+"正在吃...")
}
}
let dog = new A("dog");
let cat = new A("cat");
console.log(dog);
A {type: "dog"}
type: "dog"
__proto__:
eat: ƒ eat()
constructor: class A
__proto__: Object
打印 dog 以后会发现,结果和上面讲的原型链一模一样,所以其实 es6 的 class 就是 es5 原型链写法的语法糖,自动帮我们实现了挂载prototype的操作而已。
在es5中设置私有属性几乎是不可能实现的,外部很容易就对私有属性进行了修改:
let A = function (type) {
this.type = type
}
let a = new A("dog")
console.log(a.type) // dog
a.type = "cat"
console.log(a.type) // cat
es6中设置私有属性:
class A {
get number(){
return 1
}
}
let a = new A()
console.log(a.number) // 1
a.number = 2
console.log(a.number) // 1
get 后的函数名,是类的私有变量,返回值不会在外部被改变。同理,还有 set 可以在内部改变私有属性
let _number = 1
class A {
get number(){
return _number
}
set number(val){
if(val<10){
_number = val
}
}
}
let a = new A()
console.log(a.number) // 1
a.number = 2
console.log(a.number) // 2
a.number = 11
console.log(a.number) // 1
console.log(a._number) // undefined
注意,在 set 中,不可以写 this.number = xxx 这样就形成了死循环,调用了 set ,set中再调用set...
所以只能用一个别名变量来存储私有变量的值,并且别名变量要在 class 外部,这样就不属于类的属性,实例不会获取到。
静态方法是类方法,实例不可以调用,要用类名调用。
es5:
let A = function () {
}
A.eat = function () {
console.log("eating...")
}
let a = new A();
a.eat(); // x 报错:a.eat is not a function
A.eat(); // 正确
es6:
class A {
constructor (type) {
this.type = type // constructor声明的是私有属性和方法
}
eat(){ // 原型链上的父类方法
console.log(this.type+"正在吃...")
}
static talk(){ // static 的是静态方法
console.log("正在说话...")
}
}
A.talk()
es5:
let A = function (type) {
this.type = type
this.walk = function () {
console.log("walking")
}
}
A.prototype.eat = function () {
console.log("eating")
}
let B = function () {
A.call(this, "B") // 先执行父类的构造函数,把父类的东西挪到自己身上
}
B.prototype = A.prototype // 和父类公用一个原型链
let b = new B();
console.log(b) // 成功继承
es6:
// es6 的继承很简单,需要关键字 extends
class A {
constructor (type) {
this.type = type
}
eat(){
console.log(this.type+"正在吃...")
}
static talk(){
console.log("正在说话...")
}
}
class B extends A{ // 继承 A
}
let b = new B("b");
b.eat() // 即可调用父类方法
B.talk() // 父类静态方法
当子类需要实现自己的构造函数时,需要显示调用父类构造方法。
class B extends A{
constructor (type, voice) {
super(type); // 显示调用父类构造方法
this.voice = voice
}
}
let b = new B("b","wangwang");
b.eat()
B.talk()
es5:
function test (a, b, c) {
if (b === undefined){
b = 1
}
if (c === undefined){
c = 2
}
return a + b + c
}
console.log(test(0)) // 3
es6:
function test (a, b=1, c=2) {
return a + b + c
}
console.log(test(0)) // 3
问题:如果只想传 a , c ,还是让 b 保持默认值怎么办呢?
用 undefined 解决,回头看 es5 的方法,就会理解,当传入undefined,函数会认为是缺省,则会触发缺省值
function test (a, b=1, c=2) {
return a + b + c
}
console.log(test(0, undefined, 10)) // 11
es5: 在函数内部通过 arguments 获取传进来的参数 ( 但是 es6 已经被禁止使用 )
function test (a=0, b=1, c=2) {
console.log(arguments)
return a + b + c
}
test(10,10)
结果:
// 是一个 Arguments 对象
Arguments(2) [1, undefined, callee: (...), Symbol(Symbol.iterator): ƒ]
callee: (...)
0: 10
1: 10
length: 2
Symbol(Symbol.iterator): ƒ values()
get callee: ƒ ()
set callee: ƒ ()
__proto__: Object
可见 Arguments 对象有长度,有索引,所以——
function test (a=0, b=1, c=2) {
let arg = Array.from(arguments) // 将伪数组转换为数组
console.log(arg) // [10, 10]
return a + b + c
}
test(10,10)
所以通过 arguments 可以轻松获取到函数 传入参数 的个数和值 (不是定义的参数的个数和值)
es6:
函数名.length 可以获取到函数定义参数,且没有默认值的参数个数
function test (a=0, b=1, c=2) {
console.log(test.length) // 0 因为三个全是有默认值的
return a + b + c
}
test(10,10)
...nums
, ...
表示将所有参数写到 nums 数组中
function sum (...args) {
let res = 0
args.forEach(function (item) {
res += item
})
return res
}
console.log(sum(10,10)) // 20
同理, ...
能把 n 个参数放进一个变量数组里,也能把变量数组,拆分到n个参数里
function sum (x, y, z) {
return x + y + z
}
let nums = [1,2,3]
let res = sum(...nums) // 6
注意: ...atgs 只能在函数的参数括号中使用,用来聚合和解构数组,其他地方使用会报错
let a,b,c = ...[1,2,3] // xxxxxx 这是错的!!!
()=>{}
es5声明一个函数:
let a = function () {
console.log("hello world")
}
a()
es6 箭头函数:
let a = () => {
console.log("hello world")
}
a()
当没有参数,和有两个及其以上参数的时候,必须带(),当只有一个参数时,可以不加()
let a = () => {
console.log("hello world")
}
let a = (x,y) => {
console.log(x,y)
}
let a = x => {
console.log(x)
}
箭头函数的 => 后,可以是一个函数体,可也以是一句话表达式
// 一句话表达式,不用加函数体 {},也不用写 return,会自动计算返回
let a = (x, y) => x + y
// 等同于:
let a = (x, y) => {
return x + y
}
// 利用一句话表达式直接返回一个数组
let a = (x,y) => [x,y]
如果想返回一个对象呢?
// 这是错的
let a = (x, y) => { // 程序会把 {} 认为是函数体的开始和结束符号
"x" : x, // 这是啥?程序会报错
"y" : y
}
// 这是对的
let a = (x,y) => ( // () 可以认为是一个表达式的孵化器,像 (x+y)*2 一样,只是给必要的表达式提供一个环境
{
"x" : x,
"y" : y
}
)
// 最笨的办法
let a = (x, y) => {
return {
"x" : x,
"y" : y
}
}
es5 的普通函数:
let test = {
name : "test",
func : function () {
console.log(this.name)
}
}
test.func() // test
输出了 test ,因为 func 内的 this 指向的是调用者的作用域,就是 test 对象
es6 的箭头函数:
let test = {
name : "test",
func : () => {
console.log("name:" + this.name)
}
}
test.func() // undefined
由于简单对象(非函数)是没有执行上下文的
,所以上例中只能到最外层 windows 中找name属性,结果是 undefined。
var x = 11;
var obb = {
x: 222,
y: {
x:333,
obc: function f() {
console.log(this)
var x = 111;
var obj = {
x: 22,
say: () => {
console.log(this.x);
}
}
obj.say()
}
}
}
obb.y.obc() // 333
此处一直向上找有上下文的this,终于在函数中找到了,而函数中的 this 指向的是调用它的对象。
传统函数:this指向调用它的对象。 链接
箭头函数:this指向被定义时的上下文中的this。
es5:
let a = 1;
let b = 2;
let obj = {
a : a,
b : b
}
console.log(obj) // {a: 1, b: 2}
es6:
let a = 1;
let b = 2;
let obj = {
a,
b
}
console.log(obj) // {a: 1, b: 2}
当变量名是 key 时,可以简写。
当key是动态生成的,或是一个变量的值,es6支持将变量/表达式作为 key进行解析
es5:
let c = "123"
let obj = {
a : "a",
b : "2"
}
obj[c] = "3"
console.log(obj) // {123: "3", a: "a", b: "2"}
es6:
let c = "123"
let obj = {
a : "a",
b : "2",
[c] : "3"
}
console.log(obj) // {123: "3", a: "a", b: "2"}
// 也可以是表达式
let a = 1;
let b = 2;
let obj = {
[a+b] : "3"
}
console.log(obj) // {3: "3"}
es5:
let obj = {
hello : function(){
console.log("hello");
}
}
obj.hello()
es6:
let obj = {
hello(){
console.log("hello");
}
}
obj.hello()
set 是 es6 新增的一种数据结构,存储的成员是唯一的,不可重复。set有增删查的成员方法,没有修改方法,如果想修改建议先删除,再添加。
// 初始化
let s = new Set();
// 初始化并赋值,值不仅可以是数组,凡是可遍历对象都可以
let s = new Set([1,2,3,4]);
向set中添加数据
let s = new Set();
s.add("hello");
// 可以链式操作,因为元素唯一性,最终只有一个www
s.add("www").add("aaa").add("www");
console.log(s); // Set(3) {"hello", "www", "aaa"}
删除元素,返回 true/false
s.delete("hello"); // Set(2) {"www", "aaa"}
全部清空(删除)
s.clear(); // Set(0) {}
元素是否存在
let s = new Set([1,2,3,4]);
let res = s.has(2); // true
let res = s.has(10); // false
元素个数
let s = new Set([1,2,3,4]);
let size = s.size // 4
let s = new Set(["a","b","c","d"]);
let keys = s.keys () // SetIterator {"a", "b", "c", "d"}
let values = s.values() // SetIterator {"a", "b", "c", "d"}
let entries = s.entries() // SetIterator {"a" => "a", "b" => "b", "c" => "c", "d" => "d"}
可以看到,本质上也是一个对象,拥有键值
keys 返回了 set 的所有key的可遍历对象(SetIterator)
values 返回了 set 的所有值的可遍历对象
entries 返回了 set 的键值对的可遍历对象
es6新增的一种数据结构,用来存储键值对。任何类型都可以作为键,比如函数。
初始化时传值为一个可遍历对象,对象的各个值要有 键和值
let m = new Map();
let m = new Map([ ["a",1], ["b",2] ]); // {"a" => 1, "b" => 2}
添加/修改键值对
let m = new Map();
m.set("a", 1);
m.set("b", 2); // Map(2) {"a" => 1, "b" => 2}
// set 不仅可以添加,还可以用来修改
m.set("a", "aaa"); // Map(2) {"a" => "aaa", "b" => 2}
删除键值对,传入key,返回 true/false
m.delete("a")
console.log(m) // Map(1) {"b" => 2}
全部清空(删除)
m.clear(); // Map(0) {}
元素个数
let m = new Map([ ["a",1], ["b",2] ]);
let size = m.size // 2
查询 key 是否存在
let m = new Map([ ["a",1], ["b",2] ]);
m.has("c") // false
m.has("a") // true
let m = new Map([ ["a",1], ["b",2] ]);
m.get("c") // undefined
m.has("a") // 1
let m = new Map([ ["a",1], ["b",2] ]);
let keys = m.keys () // MapIterator {"a", "b"}
let values = m.values() // MapIterator {1, 2}
let entries = m.entries() // MapIterator {"a" => 1, "b" => 2}
keys 返回了 Map 的所有key的可遍历对象(SetIterator)
values 返回了 Map 的所有值的可遍历对象
entries 返回了 Map 的键值对的可遍历对象
for( let [key, v] of m ){
console.log(key, v);
}
// a 1 b 2
const target = {}
const source = {"a":1,"b":2}
Object.assign(target, source)
console.log(target) // {"a":1,"b":2}
es5
const a = 1;
const b = 2;
const res = 'res is '+(a+b)+' .'; // "res is 3 ."
es6
const a = 1;
const b = 2;
const c = 'hello world'
const res = `${c} res is ${a+b}` // "hello world res is 3"
功能实现:当a=1时,输出“单价为1”,当a=2时,输出“单价为2”
es5
function echoPrice(a){
if(a===1){
return "单价为1"
}else if(a===2){
return "单价为2"
}
}
console.log( echoPrice() );
es6
function Price(strings, a){
let temp = strings[0]
return temp+a;
}
let res = Price`单价为${1}` // "单价为1"
let res = Price`单价为${2}` // "单价为2"
函数名后接模板,会将由变量分割的字符串数组作为第一个参数传入函数,之后的参数依次是变量。
let arr = ["hello", "world", "1"];
let [a, b, c] = arr;
console.log(a, b, c) // "hello", "world", "1"
let [a, , c] = arr; // // "hello", "1"
解构不仅可以对数组,凡是可遍历对象都可以
let [a,b] = 'hello'
console.log(a, b) // h,e
let [a,b] = new Set([1,2,3]);
console.log(a, b) // 1,2
解构赋值还可以修改对象值
let obj = {"a":1, "b":2}; // 这里结束要加分号,与解构语句隔开
[obj.a, obj.b] = [3,4]
console.log(obj) // {a: 3, b: 4}
将解构用到遍历对象上
let obj = {"a":1, "b":2};
for( let [key,v] of Object.entries(obj) ){
console.log(key,v);
}
收集其他变量
let arr = ["hello", "world", "1",2,3,4];
let [a, b, ...others] = arr
console.log(others) // ["1", 2, 3, 4]
获取对象值
解构中的变量名默认为对象key,若要新起一个变量名,要写全 key:new_name
let option = {
"a" : "aa",
"b" : "bb",
"c" : "cc"
};
let {a:a_value, b, c} = option;
console.log(a_value, b, c) // aa bb cc
获取复杂对象值
解构时要和被解构变量保持一致的结构
let res = {
"code" : 200,
"data" : [
{
"name" : "zhang",
"age" : "20"
}
]
}
let {code, data:[{name, age}]} = res
console.log(code, name, age) // 200 "zhang" "20"
使用 export 可以导出任何结构,如变量,方法
// 1.js
export const name = "hello"
export let addr = "beijing"
export let arr = [1,2,3]
// 2.js
import { name,addr,arr } from './1.js'
console.log(name,addr,arr) // hello, beijing, [1,2,3]
多个待导出变量/方法一起导出
let a = "1";
let b = "2";
export{
a,
b
}
使用 default 来默认导出,导入时不需要放到花括号中。每个模块只可以有一个默认导出。由于只有一个默认导出,所以导入时可以随便给默认变量起名字。
// 1.js
const name = "hello"
export default name;
// 2.js
import name from './1.js'
import name2 from './1.js' // 也可以更换变量名
-----
// 1.js
const name = "hello";
let a = "1";
let b = "2";
export default name;
export {
a,
b
}
// 2.js
import name,{a,b} from './1.js'
如果非默认导出变量也像改名,那么可以用 as
// 1.js
let a = "1";
let b = "2";
export {
a,
b
}
// 2.js
import {a as a2, b as b2} from './1.js'
// 1.js
export function say(){
console.log("hi");
}
export function run(){
console.log("run");
}
export default function eat(){
console.log("eat");
}
// 2.js
import eat,{say,run} from './1.js'
say();
run();
eat();
同理也可以把函数放在一起导出
const eat = () =>{
console.log("eat");
}
const run = () =>{
console.log("run");
}
export{
eat,
run
}
// 这样做是错的,导出的最外层也是一个对象,要求值是 key-value形式,而里面是个对象,就会报错
export {
{
xxx:xxx
xxx:xxx
}
}
// 解决办法1: 使用default。因为default只能导出一个,所以后面跟对象没有歧义,就是导出一个对象
export default {
a : 1,
b : 2
}
import obj from './1.js' // 随便起一个变量名来引入。
如果要导出多个对象呢?
// 将两个对象套进一个对象中默认导出
var obj1 = {
a:1
}
var obj2 = {
b:2
}
export default{
obj1,
obj2
}
// 利用解构导入
import obj from './1.js'
let {obj1, obj2} = obj
class A{
constructor(){
this.type = 1
}
}
export {
A
}
// 引入
import {A} from './1.js'
let a = new A();
导出默认类只需要 default 后直接写类名即可‘
class A{
constructor(){
this.type = 1
}
}
export default A;
import * as Mod from './1.js'
let a = Mod.a
let res = Mod.test();
let default = Mod.default // 默认导出的变量需要用 .default 获取,不能直接用名字