一、基础知识
1.调试语句
console.log("内容",XX)
- F12 - 控制台 - 中可以查看到输出内容
- 有些网站会在控制台显示自己公司的招聘信息
2.JS代码书写位子
- 行内式(不推荐)
<a href="javscript:alert('hello world')">点我</a>
- 内嵌式
- 在script 标签内部写
- script标签可以写到head标签/body标签的最后
- 外链式
- 新建一个
.js文件,引入html文件 - 引入了文件,在标签内部再写js语言不生效
- 可以引入多个js文件
- 新建一个
<script src="XXX.js">
</script>
3. 注释
- 单行注释 //
- 多行注释 /* */
- 快捷键 alt + shift + a
4. 分号
- ES6 之后不建议加分号
- 在一行中多个代码语句,则加分号就可区分代码
5.变量
var 变量 var 变量= 值 var 变量01,变量02...
5.1 命名规则
- 必须遵守
- 数字、字母、英文下划线_、美元符号$
- 区分大小写
- 不能以数字开头
- 不能是 保留字/关键字【var】
- 不能空格
5.2 命名规范
- 建议遵守
- 有意义
- 驼峰命名规则,第二个单词及以后单词首字母大写(推荐)
- 不要使用中文
6.数据类型
6.1 基本数据类型
- Number
- 整数、浮点数、科学记数法、十六进制【0X开头】、八进制【0开头】、二进制【0b开头】、NaN【not a number】
- 控制台输出:蓝色
- 进制输出会转换为十进制,按权展开【*进制^(n-1)】
- String
- 加双引号/单引号
- 控制台输出:黑色
- Boolean
- true/false,不加双引号/单引号
- 控制台:蓝色
- Underfined
- 声明了,但未赋值
- Null
- 未来知道会被赋值一个对象
- Symbol
6.2 复杂数据类型
- 对象类型 object
- 函数 function
- 数组 array
6.3 类型检测
- typeof 变量名/typeof(变量名)
- typeof null类型,,输出结果为object
- typeof typeof 变量名
- 结果一定是 string类型
7. 类型转换
7.1 转换number
- Number(变量)
- true = 1 ,false = 0 ,null = 0 , undefined = NaN ,“abc” = NaN
- 小数正常显示
- parseInt(变量)
- 只能解析整数类型的
- parseFloat(变量)
- 可以显示浮点数
- 非加号
- 可以转换为数值型
-0/1*1 - 1 + '2' * 3 + 4 = 11
- 可以转换为数值型
7.2 转string
- 变量.toString(变量)
- undefined、null找不到对应的方法,无法转换,报错
- String(变量)
- 所有类型都能转换为字符串
- 加法运算
- +任意一边是字符串,就会进行字符串拼接
+ ""
- +任意一边是字符串,就会进行字符串拼接
7.3 转Boolean
- Boolean(变量)
" "、0、null、undefined、NaN= false
7.4 转Array
- Array.from(变量)
8.运算符
8.1 数学运算符
-
- 数值+boolean = 数值
-
-
- /
- %取余
- 10 % 3= 1
8.2 复制运算符
- =
- +=
- a += 1 ==> a = a+1
- -+
- *=
- /=
- %=
8.3 比较运算符
- ==
- 判断值
- ===
- 判断值和类型
- != 不等于
- 判断值
- !==
- 判断值和类型
-
=
- <=
-
- <
8.4 逻辑运算符
- &&
- 全true则true
- 短路用法:第一个为假,后面直接不用判断;作用避免报错
- ||
- 有true则true
- 短路用法:第一个为真,后面不判断
- !
- 取反
- !!a ===>转换为Boolean
8.5 自增自减运算符
- ++
- 前置++,先加
- 后置++,后加
- --
- 前置--,先加
- 后置--,后加
8.6 三元运算符
条件 ? 条件true : 条件false
9.分支结构
9.1 IF
if (条件) {
条件true,执行代码
}
if (条件) {
条件true,执行代码
} else {
条件false,执行代码
}
if (条件2) {
条件1 true,执行代码
} else if (条件2) {
条件2 true,执行代码
} else if (条件2) {
条件2 true,执行代码
}
if (条件2) {
条件1 true,执行代码
} else if (条件2) {
条件2 true,执行代码
} else {
条件1、2 false,执行代码
}
9.2 switch
- 对某一个变量的判断
- 判断一个变量 等于 某一个值的时候使用
- 执行效率比ifelse高,且精确执行到对应代码
switch () {
case 情况1 :
执行代码
break
case 情况2 :
执行代码
break
case 情况3 :
执行代码
break
case 情况... :
执行代码
break
default:
上诉情况都不满足执行
}
10 循环结构
- 必须的固定内容
- 初始化、条件判断、要执行代码、自身改变
10.1 while
- 自身条件没有改变,会死循环
while (条件) {
满足条件执行代码
}
10.2 do while
- 先不管条件,先执行一回,然后开始条件判断
do {
执行代码
} while (条件)
10.3 for
- 循环结构与while、dowhile不太一样
for (var i = 1; i <= 10; i++) {
执行代码
}
10.4 终止循环break
- 提前终止循环
- 跳出最近的一次循环
10.5 结束本次循环continue
- 跳过本次循环,继续执行后续的循环
11.函数
- 使用:
- 重复的代码
11.1 定义
- 声明函数
- 可以先调用再定义【预解析】
function test1() {
console.log("HEllO")
}
- 赋值式
- 必须先定义再调用
var test2 = function(){
console.log('HELLOW test2')
}
11.2 调用
函数名()
11.3 参数
- 行参
- 定义的时写的参数
- 只能在函数内部去使用
- 实参
- 调用时输入的参数
- 可以传参,可以不传参
function test3(形参){
console.log(" ")
}
var test3 = function(形参){
console.log(" ")
}
11.4 返回值
- 目标是函数执行完毕后,有结果,可以传给其他变量/后端
return- 返回值看需求
- return后面无法执行
function test(){
return 100
}
12.预解析
- js是一个解释型语言,先对代码进行通读和解释,再执行代码
12.1 解释代码 = 预解析/预解释
- 只对一个script标签内进行预解析提升,不能跨script标签;不同的是,访问函数/变量可以跨script标签
- 预解释两个内容:放在script标签前面
- 声明式函数
- 在内存中先声明有一个变量名是函数名,并且这个名字代表的内容是一个函数
- var 关键字
- 先声明有一个变量名
- 赋值式,则会报错,不是一个函数
- 声明式函数
12.2 重名问题
- 多个变量重名/多个函数重名
- 以最后一个为准
- 变量和无参函数重名
var age = 100
function age(){
console.log("age is 100")
}
console.log(age) // 输出:100
// 实际执行顺序:
// var age
// function age(){}
// age = 100
// console.log(age)
console.log(age()) // 输出:age is not a function
// 实际执行顺序:
// var age
// function age(){}
// age = 100
// console.log(age())
age()
var age = 100
function age(){
console.log("age is 100")
}
// 输出:age is 100
//执行顺序:
// var age
// function age(){}
// age()
// age = 100
12.3 函数内部定义的变量
- 在函数外访问声明式函数内部定义的变量
XXX is not defined- 函数内定义的变量 只能提升到函数的最上面,不能被外部访问
function test(a,b) {
var result = a + b
console.log(test,result)
}
console.log(result) // 输出报错: result is not defined
13 作用域
- 变量可以生效的范围
13.1 全局作用域
- 是最大的作用域
- 页面打开的时候,浏览器会自动生成一个全局作用域window,只有页面关闭才会销毁
- 可以跨script标签使用
- 可以在控制台访问到
13.2 局部作用域
- 只能在局部访问
13.3 访问规则
- 获取变量值
- 规则:就近
- 先在自己的作用域内查找,有就使用
- 没有就去上一级作用域内部查找,有就直接使用
- 若一直找到全局作用域都没有,就直接报错(is not defined)
13.4 赋值规则
- 规则:就近
- 先在自己的作用域内查找,有就直接赋值
- 没有就去上一级作用域内部查找,有就直接赋值
- 若一直找到全局作用域都没有,那么就把这个变量定义为全局变量,再给他赋值
14. 对象
- 基本上数据类型的一个集合
14.1 创建对象
- key 命名不合规则,则需要加双引号 'a+b'
var obj = {}
var obj01 = {}
obj = {
name: 'danorz',
age: 18,
location: 'zhejiang',
a: obj01,
b:function(){
console.log("object")
},
'a+b': 'ok'
}
var obj02 = new Object()
obj02.name = "danorz"
obj02.age = 20
console.log(obj02)
14.2 基本操作
- 方法一和二的区别
- key的名称,若key为'a+b',则方法一不可用obj.a+b
1. 增
// 方式一
var obj = {}
obj.name = "danorz"
obj.age = 18
//方式二
var obj01 = {}
obj01['name'] = "orz"
console.log(obj01)
2. 删
// 方式一
delete obj.name
// 方式二
delete obj01['name']
3. 改
// 方式一
obj.age = 100
// 方式二
obj01['name'] = "meimei"
4. 查
// 方式一
console.log('姓名是'+obj.name)
// 方式二
console.log('姓名是'+obj01['name'])
14.3 对象遍历
var obj = {
name: 'danorz',
age: 18,
location: 'zhejiang'
}
for (var i in obj) {
console.log(i) // key
console.log(obj[i]) //value
console.log(obj.i)//报错
}
15.不同数据类型的存储
- 背景
var str = "abc"
var strcp = str
console.log(str === strcp) // true
strcp = 'bcd'
console.log(str,strcp) //'abc' 'bcd'
var obj = {
name: 'dan',
age: 18
}
var obj02 = obj
console.log(obj === obj2) //true
obj02.name = 'orz'
console.log(obj === obj02) //true
var obj03 = {name: 'dan'}
var obj04 = {name: 'dan'}
console.log(obj03 === obj04) //false
console.log(obj03 == obj04) //false
15.1 栈
- 先进后出
- 简单类型,所有内容
- 复杂类型的定义 + 堆区地址
- 当obj01 = obj时,是两者变量的堆区地址相同
- obj01 == obj02 ,判断两者地址是否相等
15.2 堆
- 复杂类型的值
15.3 变量相互复制,且互不影响
var obj = {
name: 'danorz',
age: 18,
location: 'zhejiang'
}
var obj02 = {}
for (var i in obj ){
obj02[i] = obj[i]
}
16.数组
- 一般存储相同类型的
16.1 定义
- 字面量
=[] - 内置构造函数
=new Array()
16.2 操作
- 数组的本质就是对象
- 长度
arr.length- 可读可写
arr.length = 3留前三个- 清空数组
arr.length = 0
- 可读可写
- 索引
- 从0开始
arr[0]- 超出长度undefined 3.修改
arr[0] = "nihao"
- 增加
arr[index] = "hello"
- 遍历
var arr = [1,2,3,4]
for (var i=0, i < arr.length; i++){
console.log(arr[i])
}
- 复制
var arr = [1,2,3,4]
var arr02 = []
for (var i=0, i < arr.length; i++){
arr02[i] = arr[i]
}
arr02[2] = 'aaaa'
console.log(arr,arr02)
16.3 数组常用的方法
16.3.1 影响原数组
- arr.push(value)
- 往数组最后追加一个值
- 返回:数组的长度
- arr.pop()
- 删除最后一个值
- 返回:删除的元素
- arr.unshift(value)
- 在数组开头添加元素
- 返回:数组长度
- arr.shift()
- 删除前面元素
- 返回:删除的元素
- arr.splice()
- 删除:
- arr.splice(第几个下标开始删,删除几个元素)
- 返回:删除元素
- 增加
- arr.splice(第几个下标开始删,删除几个元素,添加的元素....)
- 返回:删除元素
- 不删除则‘删除几个元素’为0即可,‘第几个下标开始删’为插入的位置
- 删除:
- arr.reverse()
- 倒序
- 返回:倒序后的数组
- arr.sort
- 会把数字拆成字符,按照位数排序
- sort接受一个回调函数
arr.sort(function(a,b){
return a-b //从小到大
// b-a 从大到小
})
17. 排序
17.1 冒泡排序
- 挨着的两个进行比较,前一个比后一个大,则交换位置
for (var m = 0; m < arr.length-1; m++){
for (var i =0; i < arr.length-1-m; i++){
var temp = arr[i]
arr[i] = arr[i+1]
arr[i+1] = temp
}
}
16.3.2 不影响原数组
- arr1.concat(arr2,其他参数)
- 拼接
- 返回:拼接后的数组
- 复制:
arr3 = arr1.concat()
- arr.join('字符分割的符号')
- 数组转换为字符串
- 返回:没有【】,逗号被'字符分割的符号'替换
- arr.slice(开始索引,结束索引)
- 截取,包前不包后
- 返回:截取的值
- 复制:
arr01 = arr.slice() -1是最后一个值,-2倒数第二个
- arr.indexOf(value,索引开始查找)
- 查找值得下标,从前往后
- 返回:最先查找到得下标,找不到返回-1
- arr.lastIndexOf(value,索引开始查找)
- 从后面开始查找
- 返回:最先查找到得下标,找不到返回-1
16.3.3 方法
- forEach 遍历
- 回调函数,会自行调用
- item:每一项的内容; index:下标; arr:原数组
var arr = [1,2,3,4]
arr.forEach(function(item,index,arr){
内容
})
- map映射
- 回调函数
- 每一项return的值会返回到数组中
var arr = [1,2,3,4]
var arr01 = arr.map(function(){
return "aa"
})
var arr02 = arr.map(function(item){
return "<li>"+item+"</li>"
})
console.log(arr) // [1,2,3,4]
console.log(arr01) //['aa','aa','aa','aa']
document.write(arr02.join(""))
- filter()
- 回调函数
- 返回:true/false
var arr = [1,2,3,4]
var arr01 = arr.filter(function(){
return true
})
console.log(arr01) //[1,2,3,4]
var arr02 = arr.filter(function(item){
return item>3
})
console.log(arr02) //[4]
- every
- 回调函数
- 每一个都满足条件才返回true
var arr = [90,80,92,94]
var arr01 = arr.every(function(item){
return item>=90
})
console.log(arr01) // false
- some
- 只要有一个满足条件,则为true
var arr = [90,80,92,94]
var arr01 = arr.some(function(item){
return item>=90
})
console.log(arr01) //true
- find
- 可以用filter代替
- 区别
- find 找遇见的第一项
- filter 可以找出所有的,放进数组中
var arr = [1,2,3,4]
var arr01 = arr.find(function(item){
return item >= 3
})
console.log(arr01) // [3,4]
- reduce
- 叠加
var arr = [1,2,3,4,5]
//arr.reduce(function(上一个结果,每一项){
// return 上一个+每一项
//},初始值)
arr.reduce(function(prev,item){
return pre+dev
},0)
// prev 0 item 1
// prev 1 item 2
// prev 3 item 3
16.4 数组去重
- 方法一
var arr = [1,2,3,3,3,2,4,9,6,1,6]
var arr01 = []
for(var i = 0; i < arr.length ; i++){
if( arr.indexOf(arr[i]) === -1){
arr01.push(arr[i])
}
}
- 方法二
var arr = [1,2,3,3,3,2,4,9,6,1,6]
var obj = []
for( var i = 0, i<arr.length ;i++){
obj[arr[1]] = 'aaa'
}
var arr01 = []
for(var i in obj){
arr01.push(Number(i))
}
- 方法三
var arr = [1,2,3,3,3,2,4,9,6,1,6]
var set01 = new Set(arr)
var arr01 = Array.from(set01)//转换类型为array
17.2 选择排序
- 找最小的值,和索引0交换位子
for (var m = 0;m <arr.length - 1; m++) {
var minIndex = m
for ( var i = m+1; i < arr.length; i++){
if( arr[i] <arr[minIndex]){
minIndex = i
}
}
if(minIndex !== m ){
var temp = arr[m]
arr[m] = arr[minIndex]
arr[minIndex] = temp
}
}
18.字符串
18.1 创建字符串
- 字面量
- var str = 'hello' // 'hello'
- 构造函数
- var str = new String('hello') //String('hello')
18.2 方法
-
str01.length
- 只读,不能写
-
索引/下标
- str[index]
-
遍历
str1 = "hello"
for (var i = 0; i < str1.length; i++){
console.log(i,str[i])
}
18.3 统计字符串重复次数
var str1 = "abcabcab"
for (var i = 0 , i < str1.length ; i++){
var key = str1[i]
if (obj[key] == undefined){
obj[key] = 1
} else {
obj[key]++
}
}
18.4 常用的方法
- charAt(索引)
- 返回索引对应的字符
- 索引>str.length 则返回为" "
var str = "hello"
var str1 = str.charAt(0) // 'h'
var str2 = str.charAt(10) // ' '
- charCodeAt(索引)
- 返回索引对应的字符编码
- String.fromCharCode(65) = A 由ASCII编码转换为字符
var str = 'kwwww'
str1 = str.charCodeAt(0) //107 ASCII编码
- str.toUpperCase() str.toLowerCase()
- toUpperCase()全大写
- toLowerCase()全小写
- 只能转换英文
str = 'hello'
str.toUpperCase() // 'HELLO'
- 截取
- substr(开始索引,长度)
- substring(开始索引,结束索引) 前闭后开
- slice(开始索引,结束索引) 前闭后开
- substring 、 slice区别:substring取负数会失效
var str = 'technology'
str01 = str.substr(2,4) // chno
str02 = str.substring(2,4) // ch
str03 = str.substring(2) // chnology
str04 = str.slice(2,4) // ch
str05 = str.slice(2) // chnology
str06 = str.slice(2,-1) //chnolog
-
首字母大写
str.substring(0,1).toUpperCase()+str.substring(1)
-
replace(要替换的字符,替换成的字符) 替换
- 替换找到的第一个字符
- 全部替换: 正则表达式/for循环
var str = 'abbcaas'
var str1 = str.replace('a','*') // *bbcaas
- split分割
- 以某个符号为分割
- 字符串转为数组
- split('') :每一个字符串拿出来
var str = 'a,b,c,d'
var str01 = str.split(',') // ['a','b','c','d']
- indexOf('字符',索引位子) lastIndexOf
- indexOf
- 查一个字符在不在字符串内
- 找到一个就不往后找了
- -1 则不在字符串内 ; >-1 在字符串内
- lastIndexOF
- 从后往前查
- indexOf
var str = 'technology'
var str01 = str.indexOf("o")
console.log(str01) // 5
- concat 连接字符串
- 与 + 没区别
var str = 'technology'
var str01 = str.concat("kkkkk")
console.log(str01)
//technologykkkkk
- trim 去掉首位空格、trimStart() trimLeft() 去掉首空格、trimEnd()去掉尾空格
- 应用:注册界面,输入用户名
var str = ' technology '
var str01 = str.trim()
console.log(str01) // 'technology'
- json字符串转换为对象
- json字符串格式 key必须有引号'{"key":value}'
- JSON.parse(str)
var str = '{"name":"kiki","age":100}'
var obj = JSON.parse(str) //{"name":"kiki","age":100}
- 前端数据传后端数据:对象转换json格式
- JSON.stringify(obj)
var obj = {"name":"kiki","age":100} //{name:"kiki",age:100} 也可以
var str = JSON.stringify(obj)
18.5 模板字符串ES6
- `符号:换行不会报错
- `内${变量/运算表达式/三目运算}
var myhtml = "<li>XXX</li><li>XXX</li><li>XXX</li>"
document.write(myhtml)
// var myhtml = "<li>XXX</li>
// <li>XXX</li>
// <li>XXX</li>" //报错
var myhtml = `<li>XXX</li>
<li>XXX</li>
<li>XXX</li>`
document.write(myhtml)
var myname = 'hello'
var str = `my name is ${myname}. my age is ${10+8}. the son is ${1>20?'aaa': 'bbb'}`
document.write(str) //my name is hello. my age is 18. the son is bbb
19.Number
19.1 方法
- num.toFixed(保留几位)
- 保留几位小数
- 少的部分用0添加
- 返回类型:字符串,四舍五入
var num = 123.45678
var num01 = num.toFixed(2)
console.log(num01) // 123.46
var num02 = num01-0+100
console.log(num02) // 223.45999999999998
var num03 = num02.toFixed(2)
console.log(num03) // 223.46
19.2 Math对象
- console.log(Math) //查看Math对象方法
-
random随机数
- 0-1之间的随机数,包含0,不包含1
Math.random()- 取随机整数
- 0-10:
Math.fool(Math.radom()*10) - 0-10包含10:
Math.fool(Math.radom()*(10+1)) - 10-20:
Math.fool(Math.radom()*10)+10 - 10-20包含20:
Math.fool(Math.radom()*(10+1))+10
- 0-10:
-
round 四舍五入取整
Math.round(4.56)= 5
-
ceil 向上取整、fool 向下取整
- Math.ceil(4.56) = 5
- Math.fool(4.56) = 4
-
abs绝对值
- Math.abs(-10.2) = 10.2
-
sqrt平方根
- Math.sqrt(25) = 5
-
pow次幂
- Math.pow(底数,指数)
- Math.pow(3,3) = 27
-
max(多个参数) 找最大的、min(多个参数)
- Math.max(10,20,1) = 20
- Math.min(10,20,1) = 1
-
PI
- Math.PI = 3.1415926...
19.3 时间对象
- GMT 格林威治标准时间 + 8 东八区
- 是在GMT实践基础上加8小时就算是东八区的时间
-
new Data(参数1)
- 参数1:单位毫秒,在1970年1月1日0:0:0基础上加时间
-
new Data(参数1,参数2,参数3,参数4)
- 参数1:年份
- 参数2:月份,从0开始
- 参数3:日
- 参数4:小时
- 参数5:分钟
- 参数6:秒
-
new Data("2023-10-10 10:10:10")、new Data("2023/10/10 10:10:10")
19.3.1 方法
- getFullYear()
- 获取年份
- getMonth()
- 获取当前月份-1
- getDate()
- 获取日期
//今天 2023年6月26日
var date = new Date()
console.log(date.getFullYear()+"年"+(date.getMonth()+1)+"月"+date.getDate()+"日")//2023年6月26日
- getDay()
- 获取星期 周日 0 周一-周六 1-6
- getHours()
- 获取小时
- getMinutes()
- 获取分钟
- getSeconds()
- 获取秒
- getMilliseconds()
- 获取毫秒
- getTime()
- 时间戳 从1970年1月1日0点毫秒数
- 设置时间
- setFullYear()
- setDate()
- ssetHours()
- setMinutes()
- setSeconds()
- setTime()
19.3.2 定时器
- 倒计时定时器
- 只执行一次,延时执行代码
- 返回值:定时器第几个注册的
- 清除:clearTimeout()
//setTimeout(function(){
// 执行代码
//},间隔时间单位毫秒) //注册定时器
- 间隔定时器
- 每隔多长时间就再执行一次
- setInterval()
- 返回值:定时器第几个注册的
- 清除:clearInterval()
setInterval(function(){
执行代码
},间隔时间单位毫秒)//注册间隔执行器
var time1 = setTimeout(function(){
console.log("this is time1")
},1000)
var time2 = setInterval(function(){
console.log(new Date())
},2000)
console.log(btn1,btn2) //直接通过id,拿到按钮对象
btn1.onclick = function(){
console.log('btn1 click')
clearTimeout(time1)
}
btn2.onclick = function(){
console.log('btn2 click')
clearInterval(time2)
}
19.3.3 异步和同步
- 异步
- 等同步代码执行好了,才执行
- 若同步代码有死循环,则异步代码永远不能执行
- 同步
console.log("111") //同步
setTimeout(function(){
console.log("i am setTimeout")
},0)// 异步
console.log('222') //同步
// 输出
// 111
// 222
// i am setTimeout
19.3.4 倒计时
document.write(显示内容)id名称.innerHTML(显示内容)- document 会在上一次输出语句末尾,接着输出
- innerHTML会覆盖掉上一次输出
<body>
<div id="box">
</div>
<script>
var targetDate = new Date('2023/7/1')
function diffTime(current,target){
var sub = Math.ceil((target - current)/1000) //从毫秒到秒
var day = parseInt(sub/(60*60*24)) //取天数,1分钟60s 1小时60分钟 1天24小时
var hours = parseInt(sub%(60*60*24) / (60*60)) //取除了天数外,剩余多少小时
var minutes = parseInt(sub %(60*60)/60)//去掉小时剩余分钟
var seconds = sub % 60
var obj = {
day:day,
hours:hours,
minutes:minutes,
seconds:seconds,
}
return obj
}
setInterval(function(){
var currentDate = new Date()
var res = diffTime(currentDate,targetDate)
// document.write(`秒杀-${res.day}天${res.hours}时间${res.minutes}:${res.seconds}`) 会不断往网页内写入语句
// console.log(box)
box.innerHTML = `秒杀-${res.day}天${res.hours}时间${res.minutes}:${res.seconds}` //能够覆盖掉上有一次输入的
},1000)
</script>
</body>