# js-demo204 **Repository Path**: nieps/js-demo204 ## Basic Information - **Project Name**: js-demo204 - **Description**: java204班 javasceipt demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-11-16 - **Last Updated**: 2022-12-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # JS笔记 会Vue优先 非常重要!!! ## 大纲 ![JavaScript大纲](assets/JavaScript大纲.png) ## 介绍 TypeScript ts node.js =======JRE js运行环境: * 浏览器 * node.js 桌面端的应用环境 服务器端 j++ flex ------silverlight javascript----jscript -----typescript (赌对) ECMAScript(规范) -------es6 只是一个版本 JavaScript是ECMAScript(规范)的一种具体实现。(很多时间将两个概念混在一起 ) 简单概括,ECMAScript 是 JavaScript 语言的规范标准,JavaScript 是 ECMAScript 的一种实现。注意,这两个词在一般语境中是可以互换的。 - **ECMAScript 2015(ES 6,2015年6月)** ### 加载方式 * 延迟加载 defer * 异步加载 async ## 声明变量 js中全局对象window * var声明变量 > 1. 在函数外部 声明的变量 都是全局变量 > 2. 全局变量会增加到window对象上 > 3. var声明的变量不具备代码块作用域 > 4. 没有用var声明的变量 直接使用 也是全局变量 > 5. 只声明变量 不赋值,它的值是undefined > 6. var声明的变量 具有变量提升的作用 (js在执行前,会将所有声明的变量提升到前面,并初始化为undefined ) * let 声明变量 (es6引入的) > 1. 在函数外部 声明的变量 都是全局变量 , 但是它不会增加到window对象上 > 2. let声明的变量具有块级作用域 (更严谨,推荐使用它声明变量) > 3. 从表面上看,let声明的变量不具备变量提升的作用(变量必须先声明后使用),是因为它存在这暂时性死区,既在变量声明之前访问时,会报错。 * const 声明常量 > 1. const声明的常量 只能赋值一次 ,且只能在声明时赋值 > 2. 在函数外部 声明的常量是全局常量 , 但是它不会增加到window对象上 > 3. const声明的常量具有块级作用域 > 4. 因为它存在这暂时性死区,既在常量声明之前访问时,会报错。 > 5. const 的本质: const 定义的变量并非常量,并非不可变,它定义了一个常量引用一个值。使用 const 定义的对象或者数组,其实是可变的 ## 数据类型 js是一种弱类型的语言,变量的数据类型由值来决定。变量的值变了类型也跟着变。 ### 基本类型 > * 字符串(String) 用 双引号 或 单引号 括起来的字符序列 > * 数字(Number) > * 布尔(Boolean) > * 空(Null) > * 未定义(Undefined) > * Symbol (es6引入的独一无二) #### 字符串方法 js对象中的原型方法(Object.**prototype**.method)类似于java的成员方法 (成员方法通过对象调用 ) 如: ![image-20221116112928037](assets/image-20221116112928037.png) js对象上的方法(Object.method) 类似于java的静态方法 (通过类名调用 ) ![image-20221116113020531](assets/image-20221116113020531.png) 常用方法: * indexOf 查找 * split 分隔方法 参数可以是正则表达式 > js中正则表达式的定义方式: > > ~~~javascript > let reg=/^1[3456789]\d{9}$/; //验证手机号的规则 > ~~~ * substring(indexStart[, indexEnd]) 截取字符串,包含起始位置 ,不包含结束位置 * trim() 清除左右空格 * replace() 替换部分字符串 * replaceAll() 替换全部字符串 #### 数字常用方法 **`Number.NaN`** 表示“非数字”(Not-A-Number) **`Number.EPSILON`** 属性表示 1 与[`Number`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number)可表示的大于 1 的最小的浮点数之间的差值。 > [浮点精度问题参考](https://www.jb51.net/article/246218.htm) > > 应用: > > ~~~javascript > let x=0.1,y=0.2; > console.log(x+y) //0.30000000000000004 > //不能这样比较大小 > console.log(x+y==0.3) //false > //正确的比较方法 > console.log(x+y-0.3 ~~~ 常用方法: * Number.parseInt(string, radix) 开发时更多使用全局方法: parseInt(string, radix) * Number.parseFloat(string) 开发时更多使用全局方法: parseFloat(string) 原型方法: * Number.prototype.toFixed() 按照指定精度格式化数字 的 ,指定小数的位数 ~~~javascript numObj.toFixed(digits) ~~~ > digits > > 小数点后数字的个数;介于 0 到 20(包括)之间,实现环境可能支持更大范围。如果忽略该参数,则默认为 0。 ### 引用类型 * 对象(Object) * 数组(Array) * 函数(Function) 基本类型与引用类型的区别: 基本类型存储在栈中,作用域结束释放内存 引用类型的变量存储在栈中(作用域结束释放),内容存储在堆中(没有变量引用时释放)。 #### 对象 * 对象是一组无序的属性集合(键值集合,key:value集合)。 由多个 属性:值 组成,属性:值之间用逗号隔开 * 属性:值 属性是字符串类型 ,值可以是以下类型: > 1. 字符串 > 2. 数字 > 3. 布尔 > 4. 对象 > 5. 函数 > 6. 数组 > 7. null undefined symbole ###### 对象直接量 (字面量) (重点掌握) 就是对象常量 : {} ###### 使用Object构造函数 语法: ~~~javascript new Object() new Object(value) ~~~ ###### 对象合并 Object.assign() ~~~javascript //该方法是将所有参数...sources 的可枚举属性 复制到目标对象 target上 ,并返回新的对象 Object.assign(target, ...sources) // ...sources 可变参数,可以有任意个参数 ~~~ ###### 以对象为原型创建 ~~~javascript Object.create(proto) Object.create(proto, propertiesObject) ~~~ ~~~javascript let o1={ x:12 }; console.log("o1>",o1) //以对象o1为原型 创建新的对象 ,新对象会继承原型属性 let o2=Object.create(o1); o2.y=33; console.log("o2>>",o2) console.log("o2.y>>",o2.y)//自有属性 console.log("o2.x>>",o2.x)//继承于原型 o2.y=66; console.log("o2.y>>",o2.y)//自有属性 //如果属性与继承属性冲突,则会将属性添加为对象的自己属性 //继承属性不可以改变 o2.x=24; console.log("o2.x>>",o2.x)//继承于原型 console.log("o2>>",o2)//继承于原型 ~~~ ###### 总结 * 默认情况下,创建的对象都有一个原型. * 原型是一个对象,这个对象包含了一系列属性,对应的Object.prototype.属性 > 对比理解:所谓原型,如果java中所有的类都有一个父类为Object类 (Object类中的成员在所有类中都可以访问) * 原型链 (了解) * 如果变量的值是null, (空对象), 它是没有原型的 #### JSON对象 json是一种数据交换格式 > 前后端数据交换格式以前用: xml > > 现在使用:json ##### 语法规则 json对象也是对象,也是键值对集合 ,只是值的类型有要求。 JSON 的语法规则十分简单,可称得上“优雅完美”,总结起来有: - 数组(Array)用方括号(“[]”)表示。 - 对象(0bject)用大括号(“{}”)表示。 - 名称/值对(name/value)组合成数组和对象。 - 名称(name)置于**双引号**中,值(value)有**字符串、数值、布尔值、null、对象和数组**。 - 并列的数据之间用逗号(“,”)分隔 > json格式中值不允许的类型: > > * 函数 > * undefined > * Symble ![image-20221116171634341](assets/image-20221116171634341.png) 常用方法: * **`JSON.stringify()`** 方法将一个 JavaScript 对象或值转换为 JSON 字符串 * JSON.parse() 将json字符串转换为json对象 #### 数组 ##### 字面量创建数组 字面量值: [] 数组原型对应数组类[Array](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array) 数据结构: * 队列 FIFO 先进先出 * 栈 FILO 先进后出 入栈:push 出栈:pop ##### Array类型创建对象 语法: ~~~javascript new Array(element0, element1, /* … ,*/ elementN) new Array(arrayLength) ~~~ #### 函数 函数是一段程序代码,只有在调用时才会执行。 ##### function声明函数 语法: ~~~javascript function functionName(param1,param2,...) { 执行的代码 } ~~~ ##### 函数表达式 ~~~javascript let f= function(){} //将函数的字面量(匿名函数) 直接赋值给一个变量 ~~~ ##### 函数原型 所有的函数都是Function类型的对象 ,既函数的原型是Function ![image-20221117101236834](assets/image-20221117101236834.png) ##### 闭包 函数中的函数 ##### 回调函数 *回调函数*就是一个被作为参数传递的函数 #### 箭头函数 语法: ~~~javascript (param1, param2, …, paramN) => { statements } (param1, param2, …, paramN) => expression // 等价于: => { return expression; } // 如果只有一个参数,圆括号是可选的: (singleParam) => { statements } singleParam => { statements } // 无参数的函数需要使用圆括号: () => { statements } // 返回对象字面量时应当用圆括号将其包起来: params => ({foo: bar}) // 支持 Rest parameters 和 default parameters: (param1, param2, ...rest) => { statements } // 使用...rest 代表剩余参数 (param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements } //支付默认值 ~~~ #### 构造函数 ~~~javascript //自定义 构造函数 封装一个数学类 Maths //默认是普通函数 当我们在函数内使用this给函数增加属性时,它变成了构造函数 function Maths(x,y){ //在构造函数内 通过this增加的属性都是原型属性 // 给当前 Maths 构造函数增加属性 x 和 y this.x=x; this.y=y; //增加求和的方法 this.sum=function(){ return this.x+this.y; } //增加求差的方法 this.diff=function(){ return this.x-this.y; } } //增加静态方法 Maths.info=function(){ console.log("这是一个数学类的构造函数") } ~~~ 文档: ~~~javascript Maths.prototype.x Maths.prototype.y Maths.prototype.sum() Maths.prototype.diff() Maths.info() ~~~ #### this * 默认情况 下,在对象内部,this指向当前对象本身。 ~~~javascript let user={ "name":"张三", "age":23, "info":function(){ // this 指向当前对象 console.log("函数内:",this) console.log(this.name+"的年龄是"+this.age) } }; ~~~ > 在对象内部,this并不总是指向对象本身,如在函数中的函数,this指向window * 在函数或对象外部,this指向 window对象 ~~~javascript //外部this 指向window全局对象 console.log("对象外this: ",this); ~~~ * 在函数内,默认this指向window对象 * 箭头函数中的this 当我们使用箭头函数的时候,箭头函数(词法作用域)会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的。 如何保证在对象内部中出现的this总是指向函数本身? 可以 使用箭头函数,因为箭头函数具有词法作用域(箭头函数中的this始终指向对象本身) ## 基础语法 编码: * ascii 1个字节 8位 255个字符 字母 数字 常用符号 ​ a----97 * gb2312 简体中文 2个字节 16位 * gbk 是在gb2312基础上扩展的 收集了一些生僻字 unicode 编码 万国码 ------utf-8 ## 运算符 比较运算符: * === 值和类型均相等 * !== 值和类型有一个不相等,或两个都不相等 逻辑运算符: &&左边的结果是false,则右边的不再参与运算 ||左边的结果是true,则右边的不再参与运算 ## 事件 DOM: 文档对象模型(Document Object Model,简称DOM),是可以处理HTML元素的编程接口 ![image-20221118091030903](assets/image-20221118091030903.png) Vue:数据双向绑定 虚拟DOM BOM:Browser Object [Model](https://so.csdn.net/so/search?q=Model&spm=1001.2101.3001.7020),浏览器对象模型 , window ![image-20221118091948784](assets/image-20221118091948784.png) ### 事件的组成 ![image-20221118101422494](assets/image-20221118101422494.png) ### 事件参数 * this 代表事件源对象 * event 事件对象 > 两个参数: > > 1. event.target 触发事件的目标对象 > 2. event.currentTarget 绑定事件的目标对象 ### 事件传播 * 事件冒泡 事件会从内向外传递给所有的父元素 > ~~~javascript > e.stopPropagation();//阻止事件冒泡 > ~~~ * 事件捕获 事件从外向内(父元素向子元素传递) ## Ajax Ajax即**A**synchronous **J**avascript **A**nd **X**ML(异步JavaScript和[XML](https://baike.baidu.com/item/XML/86251?fromModule=lemma_inlink)) 用于异步请求 请求方式: * 同步请求 把请求提交到服务器,在服务器返回结果之前,用户只能等待,不能做其它事情 * 异步请求 请求服务器的同时,还可以正常做其它工作 ### XMLHttpRequest `XMLHttpRequest`(XHR)对象用于与服务器交互 使用该对象与服务器交互: 1. 创建该类型的对象 ### axios ![image-20221118161109367](assets/image-20221118161109367.png) #### axios返回的promise结果 ![image-20221121090744350](assets/image-20221121090744350.png) ## Promise ### 背景 回调函数: 做为参数传递的函数称为回调函数 地狱回调: 回调函数套回调函数的情况就叫做回调地狱 ### 介绍 Promise 承诺,最终会有一个结果要么成功,要么失败 ![image-20221118162716870](assets/image-20221118162716870.png) 实例方法 ![image-20221118164314432](assets/image-20221118164314432.png) ## 异步函数 async /await 要求搭配使用 async 函数是使用`async`关键字声明的函数。async 函数是 [`AsyncFunction`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction) 构造函数的实例,并且其中允许使用 `await` 关键字。`async` 和 `await` 关键字让我们可以用一种更简洁的方式写出基于 [`Promise`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise) 的异步行为,而无需刻意地链式调用 `promise`。 将异步 请求改成同步代码的操作方式 ## ES6 对象解构赋值 ### 对象 let {变量1,变量2....}= 对象 要求: * 变量1 变量2 是对应对象中的属性 ,这样对象 中属性的值就可以赋值给同名变量 * 定义变量是,使用可变参数,如 ...other , 这个时候 other是一个对象,包含了所有没有解构的属性 ### 数组 let [变量1,变量2,....]=数组 说明: * 变量1 ,变量2 对应数组下标从0开始的值 (变量的位置与数组下标一一对应 ,直接取值 ) * 定义可变参数 ...o ,这o是数组中剩余的元素组成的数组 ## ES6模块 一个模块就是一个独立的js文件 > 与Java类对比 > > servlet-api > > axios npm ### 命令 * export命令用于规定模块的对外接口 两种方式 : export 变量、函数、对象定义 ; export { 变量 ,函数 ,对象 } 推荐使用这种方式 在最后一行 > 1. export 对外输出的是一个引用 不是具体的 值 > > 2. export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值 > > 3. export命令可以出现在模块的任何位置,只要处于模块顶层就可以。通常建议放在模板的最后一行 > > ~~~javascript > export { > //输出的接口 > } > ~~~ > > > > 4. export导出变量、函数、对象等 时 可以使用 as关键字起别名,从而达到隐藏真实引用的名称 * import命令用于输入其他模块提供的功能 import { 变量,函数,对象} from 模块 >1. 提升作用 > >2. 执行静态加载 ,不能使用变量或条件语句 > >3. 通过 * 整体 导入 > > ~~~javascript > import * as 别名 from 模块 > ~~~ > > > 在es6中,假如有一个变量 name="张三",如果定义对象是 > > ~~~javascript > { > "name":name //属性名与变量名一致 可以简化 > } > ~~~ > > 简化 > > ~~~javascript > {name} // 等价于 "name":name > ~~~ > > SAP应用: 单页应用 ### export default * 本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字 * 对应的import 导入时,变量名可以任意命名,而且不需要{} * export default 在一个模块中只能出现一次 * 在一个模块中有export default的同时,还可以使用export 输出其它接口 对比export: * 使用export 导出时 ,使用 import {} 导入 * 使用export default 导出时没有用{} ,导入时也不用,名称自己定义 export和import 复合用法 ,实现类似继承 ## node.js Node.js 是一个开源与跨平台的 JavaScript 运行时环境。 它是一个可用于几乎任何项目的流行工具! Node.js 在浏览器外运行 V8 JavaScript 引擎(Google Chrome 的内核)。 这使 Node.js 表现得非常出色。 ### NPM npm 是 Node.js 标准的软件包管理器。 查看仓库源 ~~~sh npm config get registry # 查看配置 ~~~ > https://registry.npmjs.org 是默认的npm仓库地址 是国外的 访问有点慢 设置仓库源 ~~~shell npm config set registry https://registry.npm.taobao.org #更改为淘宝镜像 ~~~ ### 常用命令 #### 安装 ~~~shell npm install/i #安装指定 的模块 npm install/i 安装所有模块 ~~~ 分为两种: * 本地安装 在命令所在目录(一般是在项目下)下安装,安装到node_modules目录 下 ,这些模块只适用于当前项目 * 全局安装 ~~~shell npm install/i -g #全局安装 ~~~ 默认安装在node.js安装目录下的node_modules, 所有项目都 可以引用 ,可能通过查看 ~~~shell npm list -g #查看全局安装 的位置 ~~~ #### 卸载 ~~~shell npm uninstall #卸载本地安装 的模块 npm uninstall -g #卸载全暗安装的模块 ~~~ ### 创建项目 ~~~shell npm init -y ~~~ ### 安装信息 ~~~shell npm list/ls #查看本地安装的依赖 npm list/ls -g #查看全局安装的依赖 ~~~ ### 模块系统 1. 在node.js中通过module.exports 对象暴露接口 > 也可以通过exports暴露接口,exports是指向module.exports 的引用 ,默认情况 下 > > 直接在exports对象上增加属性没问题,但不能将一个对象直接赋值给exports > > 对象在js中是引用类型, > > ![image-20221123105957525](assets/image-20221123105957525.png) > > ![image-20221123110711015](assets/image-20221123110711015.png) 2. 通过require引入的模块 返回的就是模块对象中的exports属性 所指向的对象 > 对比:es模块 > > 1. 输出接口 > > es6是通过 export 或export default 命令 > > node.js 是通过改module.exports属性对象 > > 2. 导入 > > es6是通过import {} 或 别名 导入模块接口 > > node.js 是通过require(模块名或路径)引入,其返回值为module.exports所指向的对象 ## Vue * Vue2 > * Vue2中 Vue是一个构造函数,它需要一个参数,选项配置对象 > * 选项 是配置对象中可以定义的对象属性 > * 组件 是段公用的代码(html css js ) 作用就是复用 > * vue2 只提供了选项配置 模式 * Vue3 > * Vue是一个Object对象,不再是构造函数 Vue (发音为 /vjuː/,类似 **view**) 是一款用于构建用户界面的 JavaScript 框架 * 在浏览器中直接使用 它就是一个js文件 引入后就可以直接 使用 * 在node.js中 它就是一个模块 引入后使用 ### SPA 单页应用 * [Vite](https://vitejs.dev/) vue官方提供的构建工具 * webpack 1. 初始化应用 ~~~shell npm init vue@latest ~~~ ### 模板语法 #### 文本插值 {{响应式对象属性}} #### es6模板字符串 反向单引号 ~~~javascript ` #这里可以写带有格式的html # 这里可以使用 ${表达式} ` ~~~ #### 原始HTML 借助v-html指令显示 #### 属性绑定 * v-bind:属性名="响应式对象属性" * 简写 :属性名="响应式对象属性" * v-bind="对象" 一次绑定多个属性 注意:布尔类型的属性 由值来决定是否增加这个属性 [布尔型 attribute](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes#布尔值属性) 依据 true / false 值来决定 attribute 是否应该存在于该元素上。[`disabled`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled) 就是最常见的例子之一。 ### 响应式基础 在Vue实例上,配置选项对应的实例属性,都是是$开头,如data===$data props==$attr 内置属性 以 _ 开头 定义对象属性时尽量避免 $ _ 开头。 #### 方法 methods 选项 ,它是一个包含很多方法的对象 注意: * 不能使用箭头函数方法 因为箭头函数中的this不指向vue实例 * 使用普通函数,其中的this永远指向vue实例 (在方法中通过this引入响应式对象、调用其它方法....) ## 计算属性 * 计算属性 具有缓存作用,如果源数据没有改变,多次调用会取缓存 ; 原数据发生变化,计算属性会跟着变化 * 方法 没有缓存 作用 调用几次执行几次 ; 原数据发生改变,方法重新调用执行 computed的两种值: * 计算属性 配置成函数 (该函数为geter类型的,只读的 返回一个计算值 ) * 可写计算属性 是一个对象 ,对象中包含get /set 两个属性 分别代表读和写 ## 类和样式的绑定 class * 对象绑定 {class类名:布尔表达式, .....} 当布尔表达式为true时样式生效 * 数组绑定 1. [变量1,变量2 .....] 每一个变量的值都是一个class样式 2. [表达式] 如 [ 布尔表达式 ? "" : "" ] 如果只绑定一个样式,也可以使用 :class="变量" ## 绑定内联样式 `:style` 支持绑定 JavaScript 对象值,对应的是 [HTML 元素的 `style` 属性](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) 绑定方式: * 对象绑定 {样式属性名:值, ....} * 数组绑定 我们还可以给 `:style` 绑定一个包含多个样式对象的数组。这些对象会被合并后渲染到同一元素上 ## 列表渲染 ### 数组 * 基础语法 v-for =" item in items " item 是循环的变量名(数组中的元素) items是数组 * v-for =" (item,index) in items " index是索引 从0开始 * in关键字可以用of替换 效果一样 item of items ### 对象 * 基础 value in Object value是对象属性的值 Object 对象 * 第二个参数 属性名 (value,name) in Object name是对象属性名 * 第三个参数 代表索引 (value,name,index) in Object index 索引 ### 范围 * i in 10 循环输出 1 到10 作业: 1. 把讲的商品列表功能、购物车功能 改成vue版本的 ## 条件渲染 * v-if * v-else-if * v-else * v-show (独立使用) v-if与v-show 对比 * v-if是惰性的,只要在条件成立时才渲染;而v-show始终渲染,具有很高的初始开销 * v-if是动态的插入或删除dom元素,所以具有很高的切换开销;而v-show 是动态切换display的css属性 * v-if可以在template上使用,而v-show不能 * v-if可以和v-else v-else-if 配合使用,而v-show只能独立使用 * 使用场景: 如果频繁切换建议使用v-show,其它情况使用v-if v-if与v-for * 两者同时出现时,不要放在一起,而应该使用