export/import

export,import 是什么 我们知道,JS 模块导入导出,使用 import , export 这两个关键字 export 用于对外输出本模块 import 用于导入模块 也就是说使用 export 导出一个模块之后,其它文件就可以使用 import 导入相应的模块了 下面我们具体看看, import 和 export 到底怎么用?怎么导出模块(比如变量,函数,类,对象等) 1 导出单个变量 //a.js 导出一个变量,语法如下 export var site = "www.helloworld.net" //b.js 中使用import 导入上面的变量 import { site } from "/.a.js" //路径根据你的实际情况填写 console.log(site) //输出: www.helloworld.net 2 导出多个变量 上面的例子是导出单个变量,那么如何导出多个变量呢 //a.js 中定义两个变量,并导出 var siteUrl="www.helloworld.net" var siteName="helloworld开发者社区" //将上面的变量导出 export { siteUrl ,siteName } // b.js 中使用这两个变量 import { siteUrl , siteName } from "/.a.js" //路径根据你的实际情况填写 console.log(siteUrl) //输出: www.helloworld.net console.log(siteName) //输出: helloworld开发者社区 ``` ### 3 导出函数 导出函数和导出变量一样,需要添加`{ }` ````js //a.js 中定义并导出一个函数 function sum(a, b) { return a + b } //将函数sum导出 export { sum } //b.js 中导入函数并使用 import { sum } from "/.a.js" //路径根据你的实际情况填写 console.log( sum(4,6) ) //输出: 10 ``` ### 4 导出对象 js中一切皆对象,所以对象一定是可以导出的,并且有两种写法 #### 4.1 第一种写法 使用 `export default` 关键字导出,如下 ````js //a.js 中,定义对象并导出, 注意,使用export default 这两个关键字导出一个对象 export default { siteUrl:'www.helloworld.net', siteName:'helloworld开发者社区' } //b.js 中导入并使用 import obj from './a.js' //路径根据你的实际情况填写 console.log(obj.siteUrl) //输出:www.helloworld.net console.log(obj.siteName) //输出:helloworld开发者社区 ``` #### 4.2 第二种写法 同样是使用`export default` 关键字,如下 ````js //a.js 中定义对象,并在最后导出 var obj = { siteUrl:'www.helloworld.net', siteName:'helloworld开发者社区' } export default obj //导出对象obj //b.js 中导入并使用 import obj from './a.js' //路径根据你的实际情况填写 console.log(obj.siteUrl) //输出:www.helloworld.net console.log(obj.siteName) //输出:helloworld开发者社区 ``` ### 5 导出类 导出类与上面的导出对象类似,同样是用 `export default` 关键字,同样有两种写法 #### 5.1 第一种写法 ````js //a.js 中定义一个类并直接导出 export default class Person { //类的属性 site = "www.helloworld.net" //类的方法 show(){ console.log(this.site) } } //b.js 中导入并使用 //导入类 import Person from './a.js' //创建类的一个对象person let person = new Person() //调用类的方法 person.show() //输出:www.helloworld.net ``` #### 5.2 第二种写法 ````js //a.js 中定义一个类,最后导出 class Person { //类的属性 site = "www.helloworld.net" //类的方法 show(){ console.log(this.site) } } //导出这个类 export default Person //b.js 中导入并使用 //导入类 import Person from './a.js' //创建类的一个对象person let person = new Person() //调用类的方法 person.show() //输出:www.helloworld.net ``` ### 小结 下面我们简单总结一下 `export`与`export default`的区别 * export与export default均可用于导出常量、函数、文件、模块等 * 可以在其它文件或模块中通过import+(常量 | 函数 | 文件 | 模块)名的方式,将其导入,以便能够对其进行使用 * export default后面不能跟const或let的关键词 * export、import可以有多个,export default仅有一个。 * 通过export方式导出,在导入时要加 { },export default则不需要 * export具名导出xxx ,export default匿名。区别在于导入的时候,export需要一样的名称才能匹配,后者无论取什么名都可以。 * 模块化管理中一个文件就是一个模块,export可以导出多个方法和变量,export default只能导出当前模块,一个js文件中只支持出现一个 对于 `import` ,`export` , `export default` ,他们的用法上面的例子已经很详细的列出了,忘记的时候,可以当作参考看看 最重要的还是要明白为什么要这么写,实在不明白记住就行了。 常见考点 1. export 的基本使用 export 用于导出模块中的内容(如变量、函数、类等),使得其他模块能够导入这些内容。 ...

October 2, 2024

展开运算符

ES6 新增了很多特性,扩展运算符就是其中一个。简单的三个点号,让原本繁琐的代码瞬间变得简洁、优雅。就让我们看看它有哪些常见用法吧。 让函数的 Apply 调用方式成为过去 有时候我们需要通过 Function.prototype.apply 来调用函数,参数就放在一个数组里。 function doStuff (x, y, z) { } var args = [0, 1, 2]; // 调用函数并传参 doStuff.apply(null, args); 现在有了展开运算符,我们可以完全避免使用 apply,只需在调用函数时在数组前加上展开运算符: doStuff(...args); 代码变得更短、更简洁,也不需要一个毫无用处的 null! 合并数组 合并数组有各种方式,但是展开运算符为我们提供了一种新思路: arr1.push(...arr2) // 在数组后面添加 arr2 里的元素 arr1.unshift(...arr2) //在数组前面添加 arr2 里的元素 如果你想合并两个数组,并且想把元素放到数组中的任何位置,你可以这么做: var arr1 = ['two', 'three']; var arr2 = ['one', ...arr1, 'four', 'five']; // ["one", "two", "three", "four", "five"] 代码少了很多,还可以随意控制位置! 拷贝数组 拷贝数组是个常见的任务,过去我们使用 Array.prototype.slice 来完成,但现在我们可以通过展开运算符得到数组的副本: var arr = [1,2,3]; var arr2 = [...arr]; // 等同于 arr.slice() arr2.push(4) 这里要注意,数组里的对象仍然是引用类型的,因此实际上并不是所有内容都被“拷贝”了。 将参数或 NodeList 转成数组 跟拷贝数组类似,我们用 Array.Prototype.slice 将 NodeList和 arguments 对象转成真正的数组,但是现在我们可以使用展开运算符完成这个任务: ...

October 2, 2024

解构赋值

解构赋值概念 解构赋值语法是一种 Javascript 表达式。 通过解构赋值,可以将属性/值从对象/数组中取出,赋值给其他变量。 解构赋值是通过将结构中的各元素复制到变量中来达到“解构”的目的。但对象/数组本身不会被修改。 数组解构 基本使用 📖 可以在定义变量的同时,使用解构进行赋值 let [one, two, three] = foo; //等同于 let one = foo[0]; let two = foo[1]; let three = foo[2]; 📖 也可以先声明变量,在进行解构赋值 设置默认值 当【左边≠右边】时,可以先设置一个默认值,否则取不到值的变量会变成undefined 剩余值处理 可以使用三个点 "..."+ 参数来接收剩余的所有元素,变量名称随意,必须在最后一个参数的位置上 进阶用法 🎨 可以和split 函数结合使用,比如 let [Mother,Father] = "judy,pete".split(','); console.log(Mother) //judy console.log(Father) //pete 🎨 可以使用逗号忽略元素,比如 let [name1,,name3] = ["Julius01", "Caesar02", "Consul03"] 🎨 可以直接赋值给对象的属性,比如 let user = {}; [user.name, user.surname] = ["Ilya","Kantor"] ...

October 2, 2024

箭头函数

一、箭头函数的特点 1. 相比普通函数,箭头函数有更加简洁的语法。 普通函数 function add(num) { return num + 10 } 箭头函数 const add = num => num + 10; 2. 箭头函数不绑定this,会捕获其所在上下文的this,作为自己的this。 这句话需要注意的是,箭头函数的外层如果有普通函数,那么箭头函数的this就是这个外层的普通函数的this,箭头函数的外层如果没有普通函数,那么箭头函数的this就是全局变量。 下面这个例子是箭头函数的外层有普通函数。 let obj = { fn:function(){ console.log('我是普通函数',this === obj) // true return ()=>{ console.log('我是箭头函数',this === obj) // true } } } console.log(obj.fn()()) 下面这个例子是箭头函数的外层没有普通函数。 let obj = { fn:()=>{ console.log(this === window); } } console.log(obj.fn()) // true 3. 箭头函数是匿名函数,不能作为构造函数,不可以使用new命令,否则后抛出错误。 ...

October 2, 2024

默认参数

一、参数传递 代码语言:javascript function foo(a, b) { console.log([a, b]); } foo(1, 2); // 输出 [1, 2] 这个例子中,a 和 b 属于函数中的局部变量,只能在函数中访问。调用函数时,传递的数据会根据位置来匹配对应,分别赋值给 a 和 b。 创建函数时,function 函数名 后面括号中设定的参数被称为形参;调用函数时,函数名后面括号中传入的参数被称为实参。上面例子中,a 和 b 是形参,传入的 1 和 2 是实参。 因为形参是已声明的变量,所以不能再用 let 和 const 重复声明。 代码语言:javascript function foo(a, b) { let a = 1; // 报错,a 已声明 const b = 1; // 报错,b 已声明 } JavaScript 中所有函数传递都是按值传递的,不会按引用传递。所谓的值,就是指直接保存在变量上的值,如果把对象作为参数传递,那么这个值就是这个对象的引用,而不是对象本身。这里实际上是一个隐式的赋值过程,所以给函数传递参数时,相当于从一个变量赋值到另一个变量。 原始值: 代码语言:javascript function add(num) { return num + 1; } let count = 5; let result = add(count); // 此处参数传递的过程可以看作是 num = count console.log(count); // 5 console.log(result); // 6 引用值: ...

October 2, 2024

模版字符串

未见过的函数用法: function fun(strings,params1){ console.log(strings); console.log(params1) } fun`params1 = ${333}` // 输出分别为 // ['params1 = ', ''] // 333 不知道各位在学习或开发中有没有遇到过这样的函数调用方式呢?秉承着我没遇到的东西就要发文章来分享分享的原则,经过我查阅资料并加以学习,就让本文来带大家了解一下JS中的标签函数吧。 模板字符串 标签函数的主要作用就是处理模板字符串,所以在了解标签函数之前先了解一下模板字符串(模板字面量)吧。 基本用法 模板字符串是ES6新增的使用模板字面量定义字符串的能力,用反引号```````` 进行分隔。与使用''或""的定义的字符串字面量不同是模板字面量保留换行字符,可以跨行定义字符串。 例如: let str1 = 'xxhh\n2233' let str2 = `xxhh 2233` console.log(str1 === str2) // 结果为true 要注意的是模板字符串中的所有字符都会包含在字符串中,特别在使用缩进的时候,缩进的空格都会包含在字符串中。 let str = ` <div> <h1>xxhh</h1> </div> ` console.log(str.length) // 结果为44,包含了缩进所产出的所有空格 字符串插值 在没有模板字符串时,我们通常会使用+加法运算符来进行字符串的拼接,但有了模板字符串后我们并可通过插值占位符${}来将各字面量、变量或表达式结果来进行拼接,这样可以更容易地创建复杂和动态的字符串,同时保持代码的可读性和简洁性。这是模板字符串最常用的一个特性。 let name = 'xxhh'; let str1 = "name:"+name; let str2 = `name:${name}`; console.log(str1,str2) // name:xxhh name:xxhh console.log(str1 === str2) // true 要注意的是使用字符串插值的所有插入的值都会使用toString()强制转型为字符串,而且任何JavaScript 表达式都可以用于插值。 ...

October 2, 2024

Let/Const

Var 在 ES6 出现之前,必须使用 var 声明。但是,前端开发出现的一些问题与使用 var 声明的变量有关。这就是为什么必须要有新的方法来声明变量。首先,让我们在讨论这些问题之前更多地了解 var。 var 的作用域 作用域本质上是指变量/函数可供访问的范围。var可以在全局范围声明或函数/局部范围内声明。 当在最外层函数的外部声明var变量时,作用域是全局的。这意味着在最外层函数的外部用var声明的任何变量都可以在windows中使用。 当在函数中声明var时,作用域是局部的。这意味着它只能在函数内访问。 要进一步了解,请查看下面的示例。 var greeter = 'hey hi'; function newFunction() { var hello = 'hello'; } 这里,greeter是全局范围的,因为它存在于函数外部,而hello是函数范围的。因此,我们无法在函数外部访问变量hello。因此,如果我们这样做: var tester = 'hey hi'; function newFunction() { var hello = 'hello'; } console.log(hello); // error: hello is not defined 我们会收到错误消息,这是由于函数外部没有hello导致的。 var 变量可以重新声明和修改 这意味着我们可以在相同的作用域内执行下面的操作,并且不会出错 var greeter = 'hey hi'; var greeter = 'say Hello instead'; 又比如 var greeter = 'hey hi'; greeter = 'say Hello instead'; var 的变量提升 变量提升是 JavaScript 的一种机制:在执行代码之前,变量和函数声明会移至其作用域的顶部。这意味着如果我们这样做: console.log(greeter); var greeter = 'say hello'; 生面的代码会被解释为: var greeter; console.log(greeter); // greeter is undefined greeter = 'say hello'; 因此,将var声明的变量会被提升到其作用域的顶部,并使用 undefined 值对其进行初始化. ...

October 2, 2024

ES6 面试题

共 51 道 ES6 面试题。答案默认折叠,便于先自行作答。 1. 说说 Class 语法糖的底层实现 难度:3 · 类型:QA 题目要点 class 是基于函数构造器和原型链的语法封装,实例方法本质挂载在 prototype 上,继承通过 Object.create 构建原型链,同时通过构造函数原型链继承静态方法。super 依赖内部 [[HomeObject]] 机制定位父类方法。class 并未引入新的对象模型,而是在原型继承基础上增加语义约束与语法增强。 参考答案 这个问题的关键在于理解:class 并不是一种新的面向对象机制,而是对 原型继承(prototype-based inheritance) 的语法封装。底层仍然是函数构造器 + 原型链。 如果把 class 当作 Java 那种基于类的模型去理解,就会产生误解。 先看一个简单例子: class Person { constructor(name) { this.name = name; } say() { console.log(this.name); } static create(name) { return new Person(name); } } 它在底层大致等价于: function Person(name) { this.name = name; } Person.prototype.say = function () { console.log(this.name); }; Person.create = function (name) { return new Person(name); }; 一、实例方法的实现 ...