模块化规范
什么是模块化?
模块化就是把单独的一个功能封装到一个模块(文件)中,模块之间相互隔离,但是可以通过特定的接口公开内部成员,也可以依赖别的模块;
将一个项目拆分为若干块,每块之间以一定的形式进行通信,而每块内部的内容都是独立的;
模块化的好处?
抽离公共的代码,提高了代码的维护性和复用性;
隔离作用域,避免变量的冲突;
将一个复杂的系统分解为多个子模块,便于开发和维护;
常用的模块化规范?CommonJs
nodejs使用的commonJs规范;在nodejs中,有且仅有一个入口文件(启动文件),而开发一个应用肯定会涉及多个文件配合,因此,nodejs对模块化的需求比浏览器端要大得多;
特点
CommonJs最大的特点就是同步加载;(缺点)
每一个文件都是一个Module对象,通过关键字module.exports或者exports来暴露内容,并可以通过require来引入指定模块;
模块一旦加载一次之后就会被缓存;
工作环境
服务端;两个原因使CommonJs无法在浏览器端使用:
根本原因:CommonJs中使用了Node的api,无法在浏览器中运行。
直接原因:作为一门同 ...
nvm、npm与nrm
nvmnvm是什么?
nvm(node.js version manager)即nodejs版本管理器;可以简单操作node版本的切换、安装、查看。。。等等;与npm不同的是,npm是依赖包的管理工具。
为什么需要用nvm?
node有很多的版本,切记,并不是新版一出现,旧的版本就不去用了;在不同的项目开发过程中,可能需要我们电脑中同时存在多个不同版本的node;这时候就需要一个软件,来更好的管理这些不同版本的node同时存在于我们的电脑中。
nvm的安装
安装nvm之前先删除现有的node;在控制面板里面删了就行;
nvm下载链接;
安装路径建议不要换,因为用默认的路径环境变量就自动配置好了;即一直Next,啥也不要改;
通过nvm -v查看是否安装成功了;通过nvm list查看当前电脑上安装了那些版本的node(因为刚才卸载了,所以现在是No installations recognized.)
配置nvm:复制下面代码(配置镜像源)到nvm文件位置(过程3的第一张图),点开setting.txt
12node_mirror: https://npmmirror. ...
文件下载
文件下载方式
前端涉及到的文件下载还是很多应用场景的,那么前端文件下载有多少种方式呢?每种方式有什么优缺点呢?下面就来一一介绍。
a标签定义与用法
首先实现download功能,条件必须满足:所要下载的文件与js或当前页面同源。即window.location.protocol(传输协议)+window.location.host(域名)必须有,且一致;
如果是本地文件,请启动本地服务,使用localhost访问页面;
通过a标签的download属性来实现文件下载;download为h5中新增的a标签属性;download+href使a标签具备点击下载功能;
download属性也可以设置一个值来规定下载文件的名称;若没有设置拓展名,浏览器将自动检测正确的拓展名(.img,.png、.pdf);
兼容性测试及结果
代码
1234567891011121314151617<a href="./imgs/cs.jpg">同源图片,不带download</a></br><a href="./imgs/cs.jpg ...
JSON.stringify 深拷贝弊端
JSON.stringify 深拷贝的弊端时间对象
如果 obj 里面有时间对象,则 JSON.stringify 后再 JSON.parse 的结果,时间将转为字符串的形式,而不是对象的形式
123456let obj = { a:123, b:[new Date(),new Date()]}let newObj = JSON.parse(JSON.stringify(obj));console.log(obj,newObj);
RegExp 、Error
如果 obj 里有 RegExp (正则表达式的缩写)、Error 对象,则序列化的结果将只得到空对象;
1234567let obj = { a:123, b:/aabb[a-z]\d/, c:new Error('typeError')}let newObj = JSON.parse(JSON.stringify(obj));console.log(obj,newObj);
function、undefined、Symbol
...
深浅拷贝
对象的引用赋值
js中一旦遇到引用数据类型,就会开辟一块堆内存,将引用数据类型的值进行储存,并给这块堆内存分配一个16进制地址。
1234const info = {name:"forward",age:24};const obj = info;obj.age=23;console.log(info.age);//23
浅拷贝
浅拷贝:将第一层的数据数据完全拷贝过来,如果有引用类型,引用类型指向的是一个16进制地址,也会拷贝过来(即:拷贝的引用类型和原数据指向同一个内存地址)
(对象)如果属性是基本类型,拷贝的就是基本类型的值;如果属性是引用类型,拷贝的就是内存地址
(数组)如果数组元素(arr[index])是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化
即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址
常见的浅拷贝:
Object.assign()
concat()
slice() 返回一个新的数组对象;原始数组不会被改变。
…拓展运算符
Lod ...
栈内存和堆内存
栈内存和堆内存
我们知道程序是需要加载到内存中来执行的,我们可以将内存划分为两个区域:栈内存和堆内存。
原始类型占据的空间是在栈内存中分配的;
对象类型占据的空间是在堆内存中分配的;
值类型和引用类型
原始类型的保存方式:在变量中保存的是值本身;所有原始类型也被称之为值类型;
对象类型的保存方式:在变量中保存的是对象的引用;所以对象类型也被称之为引用类型;
JS代码是单线程的,代码从上到下执行,栈内存是先入后出的,所以上面的代码在栈的底部;
基本数据类型直接在栈内存中分配内存,变量保存的是值本身;
引用数据类型在堆内存中分配内存,并生成16进制地址,栈中的变量保存的是16进制地址,即对象的引用地址;
赋值操作是在栈中完成的:const nickName=name;将栈内存中name的值赋值给nickName,即nickName="fsllala";
const info = obj;将栈内存中obj的内存地址赋值给info,即info=0x100;
12345678910const name = "fsllala";con ...
跨域
什么是跨域
由于浏览器的同源策略限制,当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同时,需要跨域才能成功访问;
同源策略是浏览器的行为,是浏览器最核心也最基本的安全功能;
前端解决跨域方法
其实跨域问题都是找后端解决的;
误区:前端通过jsonp解决跨域原生写法123456789101.创建一个script标签 var os=document.createElement("script")2.给script一个src,src就是地址 os.src="http://suggestion.baidu.com/su?cb=qwer&wd=123"3.将script插入到页面 document.body.appendChild(os)4.回调函数处理数据 function qwer(d){ //d就是后端返回的数据 }
ajax请求12345678910111213141516$.ajax({ url:"http://suggestion.baidu.com ...
Vue3 Suspense
Suspense
等待异步组件时渲染一些额外内容,让应用有更好的用户体验(内置组件,不需要引入)
其实和2.x中的路由懒加载差不多
传统写法:效果就是 只要 子组件 还没有 引入成功,整个父组件都不会进行渲染,即所有DOM一起渲染,父组件于子组件视图一起展示 (网络慢的时候明显)
缺点:页面加载慢,加载的快慢取决于 最慢的那个加载的速度 (木桶原理既视感…)
1234567891011121314<template><!-- 父组件 --> <h1>this is parent</h1> <i-son></i-son></template><script>import iSon from "./injectSon.vue";export default { components: {iSon},};</script><style></style>
123456789101112< ...
Vue3 provide与inject
provide与inject
作用: 实现祖孙组件的通信(其实 所有的后代都能接受到数据,隔了多少代都可以,一代也不搁的也可以)
用法:父组件有一个provide来提供数据,后代组件有一个inject来接收数据;
12345678910111213141516171819202122232425262728293031<template><!-- 爷爷组件 --> <h1>this is grandParent</h1> <h3>{{name}}</h3> <h3>{{price}}</h3> <i-son></i-son></template><script>import { provide, reactive, toRefs } from "vue";import iSon from "./inject ...
Vue3 watch
watch
监听响应式数据的变化,才能够被watch所监听到;
vue2.xvue3.0vue2中的watch函数
vue2中的响应式数据是写在data、computed或者props接收的数据;才能够被watch所监听到
基本写法123456789101112131415161718192021222324<template> <div> <h2>{{ sum }}</h2> <button @click="sum++">点我加一</button> </div></template><script>export default { data() { return { sum: 1, }; }, watch: { sum(newValue, oldValue) { console.log( ...