JS 的组成【面试题】
* ES: 定义了 我们的 JS 的语法规范, 描述了语言的基本语法和数据类型
* DOM: 文档对象模型, 是由 HTML 提供的, 每一个标签就是一个 DOM
* BOM: 浏览器对象模型, 是由 浏览器 提供的, 能力: 跳转页面, 刷新页面
JS 的书写方式
- 行内(内嵌): 了解就行, 后续不要这样去写
- 内部: 直接在 body 标签末尾 书写一个标签 script 在这个标签内部, 就能书写 JS 代码学习阶段, 这个方式会常用
- 外联: 跟 内部的 方式类似, 只不过需要写一个外部的 .js 文件, 然后通过 script 的 src 属性, 引入进来,工作时常用
JS 的变量
定义: 数据存储的地方。
后续要是用这个数据,就直接通过这个变量就 OK 了。 如何创建/定义一个变量
语法:var 变量名
定义变量后, 变量内部的值, 默认为 undefined(未定义)
* 赋值
var = 变量值
JS中“=”为赋值号
变量的命名规范【面试题】
命名规范:
1. 命名要求 见名知意
2. 采用驼峰命名(多个单词拼接时,第二个单词开始的首字母大写。)
命名规则:
1. 由字母 数字 下划线 $ 组成,不能以数字开头。
2. 字母区分大小写。
3. 不能是关键字或保留字。
- JS 内部报错会阻断程序运行。
JS 的基本数据类型【面试题】
-
number 类型 不区分整数,浮点数,特殊值 NaN (如果一个值是 Number 类型,但是不能用常规数字来表达,那么就会用 NaN 来代倍)
-
String 类型 在 Js 中,只要是引号包裹起来的内容,就是 String
-
undefined 类型 未定义
-
Boolean 类型 只代表两个意思,真/假 正确/错误 true 真 false 假
-
null 类型 空对象
JS 的数据类型检测
语法:typeof 要检测的变量名 typeof(要检测的变量名) 缺点:只能用来检测基本数据类型,并且在检测 null 时,返回的不是 null 而是 object。
其他数据类型转换为 数字类型
-
Number(数据) Number 会将传入的 数据 处理为 number 类型后 返回。
- 字符串:纯数字字符串转为对应数字,空字符串和空白字符串转为 0,非空非纯数字字符串转为 NaN
- 布尔值:true 转为 1,false 转为 0
- undefined:转为 NaN
- null:转为 0
-
parseInt() 字符串转整数的方法
- 对浮点数进行取整操作
- 对数字取整直接舍弃小数部分,只保留整数
- 将字符串转为整数数字
- 将字符串转为整数数字,也包含取整功能
- 字符串中,必须是纯数字字符串或者数字字符开头的字符串,才能转换为正常数字,且只取整数部分
- 如果不是数字打头的字符串,会转换为 NaN
- 对浮点数进行取整操作
-
parseFloat()方法:字符串转浮点数方法
- 将字符串转为浮点数数字
- 满足浮点数数字字符必须在字符串开始,如果不在开始返回值都是 NaN
-
console.log(原本的数据 - 0)
- 字符串整数转换为对应数字,纯数字转换为其本身,数字开头的字符串,字母开头的字符串或纯字母字符串转换为 NaN。
- boolean 类型 true 1/false 0;
- null - 0 undefined - NaN
其他类型转 字符串类型
- 变量.toString()`方法
- String(变量)方法,有些值没有 toString(),这个时候可以使用 String()。比如 undefined 和 null
- 要转换为字符串的数据/变量名 + ''(空字符串)
转布尔类型(boolean)
Boolean(要转换的数据/变量名)
- 转为 false:NaN、0、“”空字符串、null、undefined
- 转为 true:非 0 非 NaN 数字、非空字符串
- console.log(!!要转换的数据/变量名)
JS 的算数运算符
+ - * / %
+具有特殊的地方
符号两边如果都是 数字类型,那么会求和然后参与周围程序
如果符号两边 任意一个位置出现了字符串,那么会运行拼接
符号的运算顺序:
先乘除取余,后加减;若有小括号,先计算括号内的。
JS 的赋值运算符
=+=/-=/*=//=/%=(相当于 num = num - 1)
比较运算符 (返回布尔值 true/false)
> / < / >= / <= / ==(等于 不会比较数值类型) / === (全等 会比较数值类型)/ != / !==
逻辑运算符
&& 逻辑与
运行逻辑:
1.检测符号左边的运算符布尔值是否为 true,那么运行符号右边的或者返回符号右边的
2.如果符号左边的布尔值为 false,那么直接返回左边的(不是返回左边的布尔值)
|| 逻辑或
运行逻辑:
1.检测符号左边的布尔值是否为 true,如果为 true,直接返回左侧的值(注意!不是布尔值)
2. 检测符号左边的布尔值是否为 true,如果不是,直接返回右侧的值(注意!不是布尔值)
! 逻辑非(取反)
1. 将数据原本的布尔值,做一个取反操作
2. 数据原本为true,那么返回的是false数钩原本为faLse,那么返回的是true
自增自减运算符 【面试题】
++ , --
- 跟在变量前:先将当前变量的值自增或自减 1,然后参与周围程序。
- 跟在变量后:先参与周围程序,后续在自增或自减 1。
if 分支语句
语法:if (条件) {如果条件为真,那么需要执行的代码}
条件:最后一定会成为一个布尔值,不管你写的是 变量还是表达式。
if 语句的 else...if 的写法
如果 第一个if 执行,那么会跳过后续的 else if
如果第一个 if 不执行,那么会执行后面的else if。
if 的语句 最后可以再加一个else 分支
else 分支一定要书写在 if 分支的最后。
switch 语句
- 语法: switch (要判断的变量) { case 情况 1: console.log('符合情况 1 要执行的代码') break; case 情况 2: console.log('符合情况 2 要执行的代码') break; } default: console.log('我类似于 if 分支的 else, 当前边的所有 case 都不满足的时候, 我会执行') switch 的穿刺(穿透) 现象 *如果在 case 后的代码执行完毕没有书写 break,在执行的时候, 会找到符合条件的 case 开始执行代码, 执行完毕后, 发现没有 break, 那么会继续向下执行,不管 下一个 case 是否满足条件, 一直到找到 break 或者 代码执行结束.
三元表达式
- 语法:条件 ? 条件为真时执行的代码(只能有一行) : 条件为假时执行的的代码(只能有一行)
意义:对 if 的优化
常用场景:
- 对 if 的优化
- 利用 三目 给变量赋值。
- 利用逻辑与, 进行对 if 的优化 num === 0 && console.log('失败')
循环语句
- while 循环
语法:while (条件) {满足条件时执行的代码}
一个完整循环的必要内容:
- 初始化
- 条件判断
- 要执行的代码
- 自身的改变(其实就是初始化的改变)
- do...while 循环 语法: do {要执行的代码} while (条件) while 循环在执行的时候,会先判断条件是否成立,然后再决定是否执行代码 do. . .while 循环在执行的时候,首次会直接执行代码,不管条件是否成立 如果条件失败,后续不再执行 如果条件成功,那么继续执行循环。
- for 循环 语法:for (1.初始化;2.条件;3.改变自身) {条件满足时要循环执行的代码}
for (var i = 0; i < 5; i++) {
console.log("for");
}
流程控制语句
- 两个关键字
- break 在循环中没有进行完毕的时候,因为我设置的某一个条件满足了然后执行 break 关键字,循环直接提前终止。
for (var i = 1; i <= 5; i++) {
console.log("我吃了一个包子");
if (i === 3) {
console.log("吃了三个包子,饱了,不吃了");
break;
}
}
- continue 在循环执行过程中,设置的某一个条件触发了,执行 continue 关键字,跳过本轮循环。
for (var i = 1; i <= 5; i++) {
if (i === 4) {
console.log("第四个包子,掉了,不吃了");
continue;
}
console.log("我吃了一个包子");
}
循环嵌套
简单来说, 就是循环内 再写一个循环
- 注意: 循环嵌套的时候, 初始化的变量不要相同
函数:
在JS中,函数可以理解为一段 在程序中多次出现的一段代码。
我们可以江浙一段代码放在一个盒子中,这个盒子就是 函数。
后续方便我们多次使用。
函数的参数
如果一个函数没有参数,那么函数的功能十分固定。
参数分为两个:
- 形参: function 后的小括号内书写。书写时,直接写一个变量名,然后在这个函数内部,可以使用
- 实参: 函数调用时的小括号内书写的,作用是传递给函数的形参,给形参赋值。 注意:形参和实参,都可以传递多个!但是数量要一致。实参的数量 > 形参的数量; 传递的时候 实参会按照顺序依次传递给对应的形参,多余的实参,无法在当前函数以形参的方式取使用。 多余的形参,没有值,是 undefined.
- 参数的默认值 就在需要书写 形参的后边利用 赋值号 给这个形参一个默认值 在你没有传递对应的交参的时候,形参会利用默认值
注意:如果形参有对应的实参,那么默认值不会生效
注意:需要默认值的形参,一般会放在函数的最后
函数的返回值
每一个函数内部都有一个 return ,他能决定当前函数的返回值是什么。
如果没有书写,默认返回一个 undefined
return 具有中断函数的作用,所以必须放在函数内代码最后。
函数内创建的变量,无法在函数外使用。
预解析【面试题】
-
变量 变量提升其实就是在变量定义前去使用这个变量 使用 var 声明的变量,具有变量提升的能力,换句话说,再定义变量前使用变量不会报错,但是值变成了 undefined
-
函数(声明式函数) 浏览器在解析代码时,会将函数提升到当前作用域的最顶端。
-
声明式与赋值式的区别
- 写法不同
- 赋值式不能在函数定义前去调用, 而声明式可以
原因: 赋值式是利用 变量提升 声明式是利用 函数提升
作用域【面试题】
简单来说就是变量可以使用的范围
因为变量不是在任何地方都可以使用,而这个能够使用的范围。我们称之为作用域
全局
是JS 中最大的一个作用域
在全局作用域中,创建的变量,可以在任意的地方使用
直接写在 script标签内的变量,我们称之为全局变量,这个作用域也叫做
全局作用域我们的全局作用域中有一个浏览器帮我们生成的对象(一种数据类型)
叫做window
我们在全局作用域声明的变量会自动添加到window对象中
局部(函数作用域)
在Js 中,只有函数能够创建局部作用域
在局部作用域内创建的变量,只能在当前作用域内使用,
超过这个作用域则不能使用
尽可能的多写局部变量,不写全局变量
作用域链【面试题】
作用域链 是一个 纯概念性的东西 当我们在某一个作用域内获取一个变量的时候
- 首先在自己(当前)的作用域内查找, 找到就使用, 如果没有找到, 会去自己(当前)作用域的上层作用域(父级作用域)
- 如果在 上层作用域 找到, 直接使用, 并停止查找, 如果没有找到, 那么继续向上层查找
- 如果上层作用域也没有找到, 那么会继续去上层作用域找, 直到找到全局作用域, 如果还没有找到, 此时报错
上述的也叫做 访问规则; 重点, 变量在访问的时候, 会顺着作用域 逐层向上查找, 不会逐层向下查找
赋值规则:
- 如果再给一个变量赋值的时候, 首先会在当前作用域内查找这个变量
- 如果没有找到, 那么回去上层作用域查找, 如果还没有, 继续向上
- 直到找到了全局作用域也没有找到, 在全局创建一个变量, 并赋值
递归函数
在一个函数内, 调用了 自身, 就算是一个递归函数, 只不过这个函数需要再设置一个结束条件
简单了解对象
是JS中的一种数据类型;
对象属于 引用数据类型(复杂数据类型);
算是一种数据的集合,内部可以存储任意的数据类型。
-
创建对象
- 字面量方式创建对象
var obj = { <!-- 大括号内书写的不是代码,书写数据 --> }- 内置构造函数创建
var obj1 = new Object();- 对象内对于 键(key) 的要求
- 推荐书写 属性名时,参考变量的命名规范
- 可以使用 纯数字 当属性名
- 可以使用 特殊符号(# @)但是需要使用 引号包裹
-
对象数据类型的操作(增删改查)两种语法
-
点语法 增 -> 对象.新属性名 = 对应的属性值 删 -> delete 对象.要删除的属性名 改 -> 对象.要修改的属性名 = 新的属性值 查 -> 对象.要查询的属性名
-
中括号语法(数组语法) 增 -> 对象['新属性名'] = 对应的属性值 删 -> delete 对象['要删除的属性名'] 改 -> 对象['要修改的属性名'] = 新的属性值 查 -> 对象['要查询的属性名']
-
两者的差异
- 如果对象的属性名 是符合变量的命名规范的话,那么这两种语法没有任何差异。
- 如果对象的属性名 不符合变量的命名规范的话,使用中括号语法
- 如果用的是变量,也需要使用中括号语法。
-
for in 循环遍历对象
-
//语法:for...in
var obj = {
name: "qwer",
age: 18,
str: "asdf",
};
for (var a in obj) {
// console.log(a)
console.log(a, obj[a]);
}
数组数据类型
数组: 一个存放一组数据的集合 简单来说, 我们将一组数据, 存放到一个盒子中, 这个盒子就是一个数组 数组的创建
- 字面量的方式 (常用)
// 1. 字面量的方式
var arr = [] 创建一个空数组
var arr = [1, 2, 'qwe', 'rty', true, false, undefined, { name: 'QF001' }]
console.log(arr)
- 内置构造函数
// 2. 内置构造函数
var arr = new Array() 空数组
var arr = new Array(5) 创建一个 长度 为 5 的空数组
var arr = new Array(1, 2, 3, 4, 5) // 创建一个 内容为 1 2 3 4 5 的数组
console.log(arr)
数组的 length 其实就是数组的长度, 由数组内部多少个 成员(数据) 来决定的 跟数组每个成员的值, 没有任何关系
// length
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var arr1 = [100, 200, 300, 400, 500];
console.log(arr1);
console.log(arr1.length);
数组的 索引(下标) 下标表示的是 数组当前位置 从 0 开始!!! 到 数组.length - 1 结束
冒泡排序
var arr = [9, 8, 7, 6, 5, 4, 3, 2, 1];
console.log("原数组", arr);
for (var k = 0; k < arr.length - 1; k++) {
// 决定内部的 冒泡排序执行多少次
// 内循环: 冒泡排序的核心代码
for (var i = 0; i < arr.length - 1 - k; i++) {
console.log("当前对比的是: ", arr[i], arr[i + 1]);
if (arr[i] > arr[i + 1]) {
var tem = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = tem;
}
}
}
console.log(arr);
选择排序
var arr = [9, 3, 6, 2, 4, 1, 8, 5, 7];
for (var k = 0; k < arr.length; k++) {
// 1. 创建一个变量, 存储当前假设的 最小值的下标
var minIndex = k;
// 2. 遍历数组, 寻找真实最小值的下标
for (var i = k + 1; i < arr.length; i++) {
if (arr[minIndex] > arr[i]) {
minIndex = i;
}
}
// 3. 经过上述循环遍历之后, minIndex 一定是 真实最小值的下标, 所以此时交换两个下标的值
var tem = arr[k];
arr[k] = arr[minIndex];
arr[minIndex] = tem;
}
console.log("选择排序后: ", arr);
数据类型之间的区别
数据类型之间的区别
- 基本数据类型
- 复杂数据类型
存储的区别
- 基本数据类型 (string, numbe, undefined, null, boolean) 直接将数据类型存储到 栈内存中
- 复杂数据类型 (object, array, function) 将数据本体, 存放在堆内存中, 然后将指向堆内存的地址, 存储在 变量名中, 最后变量名存储在 栈内存中
赋值的区别
- 基本数据类型 直接将数据赋值给另一个变量; 赋值完成之后, 两个变量没有任何关系 类似于, 我有一张考试卷子, 我复制出来一份给你, 然后你对你的卷子有任何修改, 都不会影响我这一张卷子
- 复杂数据类型 因为 复杂数据类型的变量名中 存储的是指向一个堆内存的地址, 所以在做赋值的时候, 是把这个地址赋值给另一个变量了 所以修改另外一个变量的时候, 会影响自身 类似于: 我有一个房间的钥匙, 然后我将钥匙复制一份, 给你一个, 你后续能够进入这个房间了, 后续如果你对这个房间做了任何修改 在我进入房间的时候, 我都能看到
比较的区别
- 基本数据类型 直接将数据进行对比
- 复杂数据类型 因为变量内部存储的是 一个地址, 所以对比时, 对比的是地址, 而不是真正的值
传参的区别
- 基本数据类型 将数据拷贝一份传递给形参, 在函数内对形参的修改并不会影响外界
- 复杂数据类型 将变量内部存储的地址, 赋值给形参, 也就是说, 函数内部的形参, 和外部的变量, 共同享用同一个地址 所以在函数内对形参的修改会影响外界
数组的常用方法
数组的常用方法
- push
-
语法: 数组.push(数据) -
作用: 将这个 "数据", 追加到数组的末尾, 向数组末尾, 添加新数据 -
返回值: 追加新数据后, 数组的最新的长度 length
-
- pop
-
语法: 数组.pop() -
作用: 删除数组的最后一项 -
返回值: 删除的哪一项对应的值
-
- unshift
-
语法: 数组.unshift(数据) -
作用: 将这个 "数据", 添加到数组的开头 -
返回值: 追加新数据后, 数组的最新长度 length
-
- shift
-
语法: 数组.shift() -
作用: 删除数组的第一项 -
返回值: 删除的哪一项对应的值
-
- reverse()
-
语法: 数组.reverse() -
作用: 反转数组 -
返回值: 反转后的数组
-
- sort()
-
传参数:数组.sort(function (a,b) {return a-b}) 数组.sort(function (a,b) {return b-a})语法:数组.sort() -
作用:对数组进行排序
-
返回值:不穿参数:将排序后的数组返回
-
- splice()
-
语法:数组.splice(开始索引,多少个);数组.splice(开始索引,多少个,要插入的数据 1,要插入的数据 2,...) -
作用:截取数组 类似于剪切; -
返回值:截取到的数据(以数组的形式) 数组方法中,只有以上 7 种可以改变原数组。
-
- slice()
-
语法:数组.slice(开始索引,结束索引)
-
作用: 类似与复制 -
返回值:复制到的的数据(以数组的形式)
-
- concat()
-
语法:数组.concat(数据1,数据1,数据3,...) -
作用: 将小括号内的数据,合并当 当前数组中 -
返回值:返回合并后的数组
-
- join()
-
语法:数组.join('连接符') -
作用:通过连接符,将数组的每一项合并起来,如果不传递连接符,默认逗号连接。 -
返回值:连接好的数据(字符串类型的)
-
- indexOf(默认从[0] 找到数组的末尾)
-
语法:数组.indexOf(数据); 数组.indexOf(数据 ,从哪里开始) -
作用:在数组内寻找 你传入的 数据 -
返回值: 如果找到了,返回数据第一次出现的下标 如果没找到,返回 -1
-
- lastIndexOf(默认从数组的末尾, 找到 [0])
-
语法:数组.lastIndexOf(数据); 数组.lastIndexOf(数据 ,从哪里开始) -
作用:在数组内寻找 你传入的 数据 -
返回值:如果找到了,返回数据第一次出现的下标 如果没找到,返回 -1
-
- forEach
-
item: 遍历数组的当前项 index:item对应的下标 origin:对应的原数组语法:数组.forEach(function (item;index;origin) {遍历数组需要执行的代码}) -
作用:遍历数组 -
返回值:没有返回值,永远是undefined
-
- map
-
语法:数组.forEach(function (item;index;origin) {遍历数组需要执行的代码}) -
作用:映射数组,映射出来一个数组长度与原数组一模一样的数组,但新数组的值,取决于return -
返回值:映射出来的数组
-
- filter
-
语法:数组.filter(function (item;index;origin) {遍历数组需要执行的代码}) -
作用:过滤数组 -
返回值:过滤后的新数组,过滤条件取决于 函数内的return
-
- find
-
语法:数组.find(function (item;index;origin) {遍历数组需要执行的代码}) -
作用:查找数据 -
返回值:在数组内找到的第一个符合条件的数据(不是数组) 如果找不到 返回 undefined
-
- findIndex
-
语法:数组.findIndex(function (item;index;origin) {遍历数组需要执行的代码}) -
作用:查找数据 第一次出现的 下标 -
返回值:在数组内找到的第一个符合条件的数据 的下标 如果找不到 返回 -1
-
- every
-
语法:数组.every(function (item;index;origin) {遍历数组需要执行的代码}) -
作用:判断数组的每一项是否都符合条件 -
返回值:true 都符合条件 false 至少有一个不符合条件
-
- some
-
语法:数组.some(function (item;index;origin) {遍历数组需要执行的代码}) -
作用:判断数组是否 有一项 符合条件 -
返回值:true 最少有一项符合条件 false 都不符合条件
-
- reduce
-
语法:数组.reduce(function (prev, item, index, origin) {}, init) prev: 表示初始值(需要传递init) 或者表示数组[0]的值(需要不传递init) item: 如果传递了 init, item 的值为 数组[0] 如果没有传递 init, item 的值为 数组[1] index/origin: 与forEach 相同
-
注意:
init 为可选项
如果书写了 init, 那么 prev 的第一次的值, 就是由 init 传递的, 然后 item 的值是从 [0] 开始的
如果没有书写 init, 那么 prev 的第一次的值, 是数组 [0] 的值, 然后 item 的值使用[1]
* 作用: 累加(叠加)
* 返回值: 循环运行后的值
字符串的常用方法
- charAt
-
语法:字符串.charAt(索引) -
作用:找到字符串中这个索引对应的文本 -
返回值:查询到的值 如果没有找到,返回一个空字符串
-
- charCodeAt
-
语法:字符串.charCodeAt(索引) -
作用:找到字符串中这个索引对应的文本 的十进制编码 -
返回值:查询到的值对应的编码 如果没有找到,返回NaN
-
- toLowerCase
-
语法:字符串.toLowerCase() -
作用:将字符串全部转换为 小写 -
返回值:转换后的字符串
-
- toUpperCase
-
语法:字符串.toUpperCase() -
作用:将字符串全部转换为 大写 -
返回值:转换后的字符串
-
- substr 了解即可
-
语法:字符串.substr(开始索引,多少个) -
作用:截取指定范围的字符串 -
返回值:截取到的字符串。
-
- substring
-
语法:字符串.substring(开始索引,结束索引) -
作用:截取指定字符串 -
返回值:截取到的字符串。
-
- slice
-
语法:字符串.slice(开始索引,结束索引) - 参数的特点: 1.包头不包尾;包含开始索引,不包含结束索引 2.参数接受负数(相当于 数组.length + 负数) 3.参数可以不传递。 =>结束下标不传,相当于 从开始下标复制到数组的尾部 =>两个参数都不传递,相当于从[0] 复制到数组的末尾。
-
作用:截取指定字符串 -
返回值:截取到的字符串。
-
- concat
- 语法:字符串.concat(数据1,数据2,...)
- 作用:将数据合并到字符串中
- 返回值:合并后的字符串。
- split
-
语法:字符串.split(分隔符) -
作用:在当前字符串中找到指定的分隔符,然后根据分隔符将当前字符串拆分开,以数组的形式保存。 -
注意:返回值:拆分后的数组。-
- 字符串中, 有对应的分隔符: 将字符串根据分隔符分隔开
-
- 字符串中, 没有对应的分隔符: 将字符串当成一个整体, 放在数组中
-
- 如果传递的是 空字符串: 将字符串每一个字符串全都分隔开, 放在数组中
-
-
- indexOf
-
语法:字符串.indexOf(数据,开始下标) -
作用:查找数据在字符串中的位置 -
返回值:找到时返回数据在字符串中的下标 -
找不到返回-1
-
- lastindexOf
-
语法:字符串.lastindexOf(从最后开始查找) -
作用:查找数据在字符串中的位置 -
返回值:找到时返回数据在字符串中的下标 -
找不到返回-1
-
- trim (纯木)
-
语法:字符串.trim() -
作用:去除字符串左右两边所有的空格 -
返回值:去掉空格后的字符串
-
- trimStart(trimLeft)
-
语法:字符串.trimStart() -
作用:去除字符串左边所有的空格 -
返回值:去掉空格后的字符串
-
- trimEnd(trimRight)
-
语法:字符串.trimEnd() -
作用:去除字符串右边所有的空格 -
返回值:去掉空格后的字符串
-
- includes
-
语法:字符串.includes(字符串片段) -
作用:判断 当前字符串中 是否拥有这个字符串片段 -
返回值:布尔值 true 拥有 -
false 没有
-
- startsWith
-
语法:字符串.startsWith(字符串片段) -
作用:判断 当前字符串开头中 是否拥有这个字符串片段 -
返回值:布尔值 true 拥有 -
false 没有
-
- endsWith
-
语法:字符串.endsWith(字符串片段) -
作用:判断 当前字符串结尾中 是否拥有这个字符串片段 -
返回值:布尔值 true 拥有 -
false 没有
-
- replace
-
语法:字符串.replace('要被替换的字符串','新的字符' ) -
作用:在字符串中 先找到 要被替换的字符串,找到后将 新的字符串 替换过去 -
返回值:替换后的字符串 -
找不到返回原字符串。
-
严格模式
严格模式:
*其实就是因为 JS 初期的不严谨, 后续特意推出了一个严谨的版本, 我们叫做严格模式
*在 JS 中默认是关闭的, 如果要打开, 需要在 JS 开始的位置, 书写一个字符串 'use strict'
* 在严格模式中, 变量 必须定义
* 函数的形参名不能重复
进制转换与保留小数
- 进制转换 (了解) => 十进制转换成其他进制 十进制的数字.toString(你要转换的进制数) => 其他进制转换成十进制 parseInt(数字, 将数字视为x进制的数字然后转换成10进制)
- 保留小数 (掌握) => 要保留小数的数字.toFixed(要保留几位小数) 采用四舍五入的方式, 并且返回的是一个 字符串
定时器与倒计时器
- 定时器
setInterval(function () {
// 定时器每次执行的时候, 要执行的代码
console.log('当前定时器, 每 1 秒, 执行一次')
}, 500) // 时间单位是毫秒
- 倒计时器
setTimeout(function () {
console.log('当前倒计时器, 会在 3 秒后执行一次')
}, 3000)
返回值: 含义: 表明当前页面有多少个定时器或者倒计时器 作用: 停止当前定时器或者倒计时器 关闭定时器的注意事项: 关闭的时候, 有两个方法 clearTimeout/clearInterval; 可以混用
但是不推荐混用
数学方法
- random
- 返回一个 0~1 之间的随机数, 不包含1.
- round 将一个小数 进行四舍五入取整
- console.log(Math.round(1.4))
- ceil 将一个小数 进行 向上 取整
- console.log(Math.ceil(1.4))
- floor 将一个小数 进行 向下 取整
- console.log(Math.floor(1.4))
- abs 绝对值
- console.log(Math.abs(1.4))
- sqrt 求平方根
- var num = Math.sqrt(9)
- console.log(num)
- pow
- var num = Math.pow(3,4) //求数字3的4次幂
- console.log(num)
- max
- var num = Math.max(3,4)
- console.log(num)
- min
- var num = Math.min(3,4)
- console.log(num)
时间对象
时间对象
不传参数,直接获取当前时间
var timer = new Date();
console.log(timer)
传递参数,传递字符串
var timer = new Date('2000-5-3 12:13:14');
console.log(timer)
传递数字,最少传递两个
var timer = new Date(2002,5,3,12,12,12);//JS中,月份的表示是从0~11.
console.log(timer)
时间对象的获取类方法
- getFullYear 获取年份
- getMonth 获取月份
- getDay 获取周几
- getDate 获取一个月中的哪天
- getHours 获取哪一小时
- getMinutes 获取分钟
- getSeconds 获取秒
- getTime 获取毫秒数
时间对象的设置类方法
- setFullYear 设置年份
- setMonth 设置月份
- setDate 设置一个月中的哪天
- setHours 设置哪一小时
- setMinutes 设置分钟
- setSeconds 设置秒
- setTime 设置毫秒数
- setDay 不管用
BOM
- 获取浏览器窗口的尺寸
- 宽度:window.innerWidth
- 高度:window.innerHeight
- 浏览器弹出框
- window.prompt() 输入框
- window.alert() 弹出框
- window.confirm() 询问框
- 浏览器的地址信息
- 在 window 中,有一个对象location,他是专门用来 存储浏览器的地址信息
- location这个对象中有一个属性是href 我们可以给他重新赋值一个地址,实现页面的跳转还有一个方法,reload,我们调用之后,可以刷新当前页面
- 通过 BOM 获取到 浏览器的版本信息 (了解) navigator
- 浏览器的 onload 事件
- 会将 内部的代码 等到页面所有内容加载完毕后执行
- 浏览器的滚动事件
onscroll 事件在元素滚动条在滚动时触发。
- window.onscroll = function () {}
3.1 浏览器的滚动距离
- 思考: 浏览器滚动了吗?
- 回答: 没有滚动, 其实是浏览器内的页面在滚动
语法1: document.body.scrollTop
语法2: document.documentElement.scrollTop
区别:
- IE 浏览器 (了解) 没有 DOCTYPE, 那么使用两个中任意一个都可以 有 DOCTYPE, 那么只能使用 documentElement
- Chrome 和 火狐浏览器 没有 DOCTYPE, 用 body 有 DOCTYPE, 使用 documentElement
- Safari 这两个都不能使用, 使用 window.pageYOffset
3.2 浏览器的横向滚动距离
语法1: document.body.scrollLeft
语法2: document.documentElement.scrollLeft
区别参考上边的
// 1. 获取浏览器窗口的尺寸 (通过 window 可以操作 BOM)
var aaa = 100
console.log(window)
console.log(aaa)
console.log(window.aaa)
console.log('高度', window.innerHeight)
console.log('宽度', window.innerWidth)
console.log('高度', innerHeight)
console.log('宽度', innerWidth)
// 2. 浏览器的弹窗框
var str = window.prompt('请您输入一个内容') // 输入框
alert('一个弹出框') // 弹出框
var boo = confirm('您确定跳转页面吗?') // 询问框
console.log(boo)
// 3. 浏览器的地址信息
console.log(window.location)
BOM 本地存储
- storage (四套润此)
-
localStorage 浏览器本地存储,持久存储,一旦存储永久存在 只能存储基本数据类型(一般是字符串) 能够跨页面通讯 我在A页面存储,但是在B页面能够获取到,那么就是跨页面通讯
-
// localStorage
// 1. 新增一个本地存储
/window.localStorage.setItem(key, value) // key 相当于变量名, value 你真正要存储的值
window.localStorage.setItem('WX', 'QF001')
window.localStorage.setItem('QQ', 'QF888')
// 2. 删除一个本地存储
window.localStorage.removeItem(key) // 你要删除哪一个本地存储, 就把这个 key 写成哪一个
window.localStorage.removeItem('WX')
// 3. 清空本地存储
window.localStorage.clear()
//4. 查询一个本地存储的值
//返回值:
//查询到 -> 把这个 key 对应的 value 返回出来
//没有查询到 -> 返回一个 null
var res = window.localStorage.getItem('WX1234567890')
console.log(res)
//5. 存储引用数据类型(数组---对象)
// 错误存储数组
var arr = [1, 2, 3, 4, 5]
window.localStorage.setItem('arr', arr)
var res = window.localStorage.getItem('arr')
console.log(res)
// 错误存储对象
var obj = {
name: 'QF001',
age: 18
}
window.localStorage.setItem('obj', obj)
var res = window.localStorage.getItem('obj')
console.log(res)
/**
* 在 JS 中 有一个对象叫做 JSON, 她提供了两个方法
* 1. JSON.stringify(传入要转换的数据) 能够将其它类型的数据, 转换为 JSON 格式的字符串
* 2. JSON.parse(传入要转换的数据) 能够将 JSON 格式的字符串, 转换为 原本的数据类型
*/
var obj = {
name: 'QF001',
age: 18
}
var newObj = JSON.stringify(obj)
var arr = [1, 2, 3, 4, 5]
var newArr = JSON.stringify(arr)
// console.log(obj)
// console.log(newObj)
// console.log(arr)
// console.log(newArr)
window.localStorage.setItem('arr', newArr)
window.localStorage.setItem('obj', newObj)
var arr1 = JSON.parse(window.localStorage.getItem('arr'))
var obj1 = JSON.parse(window.localStorage.getItem('obj'))
console.log(arr1)
console.log(obj1)
* sessionStorage
浏览器本地存储,临时存储,关闭浏览器后,存储内容自动消失
如果想要跨页面通讯,必须是从本次页面跳转的才可以打开
增; 删; 清除; 获取; 和localStorage一样
- cookie (kuki)
-
只能存储字符串,且有固定格式( key=value) -
存储大小有限制 -
操作cookie 必须依赖服务器(本地启动文件不能运行 cookie) -
跟随前后端交互,自动携带 将来前端向后端发送请求时,如果 cookie 内有数据,那么会自动携带 -
前后端操作 前端:JS 后端:任何一个后端语言都可以操作 cookie -
存储依赖域名 哪一个域名存储, 哪一个域名能够使用, 不能跨页面通讯
-
cookie 和 storage 的区别【面试题】
- 出现时间: cookie 是有JS的时候就存在了 storage H5出现后才出现
- 存储大小 cookie 4kb storage 20MB/5MB
- 前后端交互 cookie 请求时自动携带 storage 请求时不会自动携带,可以手动携带
- 前后端操作 cookie 前后端都可以操作 storage 只有前端 JS 能操作
- 过期时间 cookie 默认会话级别,但是可以手动设置过期时间 storage 不能手动设置过期时间
- 两个 storage (localStorage;sessionStorage) 有什么区别?
- 过期时间
- 跨页面通讯
- 共同点:
- 只能存储字符串,不能存储复杂数据类型
- 直接存储其他数据类型,获取回来的也是字符串类型
- 在 JS 中 有一个对象叫做 JSON, 她提供了两个方法
- JSON.stringify(传入要转换的数据) 能够将其它类型的数据, 转换为 JSON 格式的字符串
- JSON.parse(传入要转换的数据) 能够将 JSON 格式的字符串, 转换为 原本的数据类型
DOM
文档对象模型;操作 HTML 标签的能力
获取一个元素(标签、节点、DOM节点)
移除一个元素
创建一个元素
向页面中添加一个元素
给页面绑定事件(单击、双击、键盘按下...)
获取元素的一些属性
获取元素的css样式
给一个元素添加css样式
- DOM 的核心是 document 对象
- document 对象是浏览器内置的一个对象,里面存储着专门用来操作元素的各种方法
获取页面的常规元素
- 通过元素的id名获取标签
var id_ele = document.getElementById("id_box");
console.log(id_ele)
- 通过元素的 class 名
注意:
- getElementsByClassName Element(爱了门特)
- 获取到的元素, 放在了一个长得很像数组的数据结构内
- 我们可以通过下标去获取到准确的 DOM节点, 也可以通过 length 知道获取了多少个元素
- 但是数组的一些方法不能使用, 比如 forEach, map....
- 我们给这个数组起了个名字叫做 伪数组
var cla_box = document.getElementsByClassName("class_box");
console.log(cla_box)
- 通过元素的标签
var div_box = document.getElementsByTagName("div");
console.log(div_box)
- 类似 css 选择器的方式 document.querySelector (快润设莱克特) 获取到的是页面中第一个符合的标签
var new_div_box = document.querySelector('div')
var new_div_box = document.querySelector(".class_box");
console.log(new_div_box);
- 获取到页面中所有符合要求的 标签 也是一个伪数组的形式, 但是能使用 forEach 个人建议, 使用伪数组的时候, 不要使用数组的方法 最好的方式将这个伪书组转换成真实数组 var arr = [...伪数组]
var new_div_box = document.querySelectorAll('div')
var new_div_box = [...document.querySelectorAll("div")];
console.log(new_div_box);
操作元素的属性
获取到DOM 节点的属性,并直接渲染到页面
- 获取标签
var boxO = document.querySelector('#box_o')
var boxT = document.getElementById('box_t')
- innerHTML 获取标签内部的结构
console.log(boxO.innerHTML)
// 设置的时候能够解析字符串中的 html 标签
boxT.innerHTML = '<span>hello<span>'
- innerText 获取元素内部的文本 (获取不到html 标签)
console.log(boxO.innerText)
// 设置的时候会将字符串的所有内容添加到标签的文本区, 字符串中哪怕是写了标签, 他也不认识
boxT.innerText = '<span>hello</span>'
- 获取元素的某个属性 (包括自定义属性)
console.log(boxT.getAttribute('a')) // getAttribute(鹅腿比u特) 获取到当前标签的这个属性对应的值
console.log(boxT.getAttribute('id')) // getAttribute 获取到当前标签的这个属性对应的值
- 设置元素的某个属性
boxT.setAttribute('my_box', 'QF001') // 新加一个属性
boxT.setAttribute('a', 'QF666') // 修改原有的属性
- 删除元素的某一个属性
boxT.removeAttribute('a') // 将这个标签的属性a, 删除
- H5自定义属性
- 属性名: data- 后的内容 如果一个 H5 自定义属性写为: data-id="QF001" 属性名: id 属性值: 'QF001' data- 的作用仅仅表示这是一个 H5的自定义属性
// 增加
boxEle.dataset.name = 'wang'
// 删除
delete boxEle.dataset.id
// 获取
console.log(boxEle.dataset.xbox)
- style 专门用来给某个元素添加 css 样式 添加的样式是行内样式
boxEle.style.width = '100px'
boxEle.style.height = '100px'
boxEle.style.backgroundColor = 'pink'
- className 专门用于操作元素类名; 设置类名的时候, 不管之前有多少个, 直接全部覆盖
boxEle.className = 'new_box'
console.log(boxEle.className)
- classList 也是用于操作元素类名的, 具有一些方法, 如下所示
// 新增一个类名
boxEle.classList.add('new_box')
// 删除一个
boxEle.classList.remove('new_box')
console.log(boxEle.classList)