javascipt 介绍
是一门编程语言,由布兰登艾奇创作
javascript 组成部分
ECMAScript 标准语法、DOM、BOM
ECMAScript 变量
官方的定义:在计算机内存中开辟一块空间用来储存数据,存储的时候取一个数据时候取一个名称,使用的时候根据名称去取到这个数据。
存储变量的过程叫变量定义(声明)
定义变量语法:
- var 变量名 = 数据
- var 关键字
- 变量名
- = 赋值操作 把右侧数据给左侧变量名
- 数据
变量未赋值使用这个变量,会得到什么?
- 得到是 undefined
变量未定义,使用这个变量,会得到什么?
- a is not defined 未定义
变量命名规则和规范
规则:
- 变量名必须是数字、字母、下划线、$组成,但是不能以数字开头
- 变量名严格区分大小写
- 命名中间不能有空格,不能以中文命名
- 不能是关键字和保留字
+ 关键字是js正在使用的 if else for while…
+ 保留字是js将来可能使用
规范:
- 命名尽量语法化
- 多个单词组成,小驼峰命名法 从第二个单词开始首字母大写
注意:= 并不是数学上的等于 在任何编程语言里面都是赋值操作
js的数据类型
基础的数据类型
- 数值 number
- 字符串 string
- 布尔 boolean
- undefined
- null
引用数据类型(复杂数据类型) 地址
- function 函数
- object 对象
- array 数组
基础数据类型
数值类型 Number
字符串类型 String
布尔类型 Boolean
undefined 变量声明未赋值(js是独有)
null 代表空
undefined与null区别?
null是实实在在的空 一般用于变量定义时候不知道给什么类型值,一般就给它为null;undefined是变量定义未赋值的时候得到,不是我们自己给它的
字符串
含义: 由字符组成的串
字符串区分: ‘’ “”
字符串储存: 底层存储是和数组相同的
ASCII编码表
- 计算机最早用于军事
- 计算机最底层存储方式 二进制
- 0-9
- a-z
- A-Z
- 特殊符号 , . ! @ #
- 把英文和符号对应设置一个数字 数字转成二进制 存入计算机
- ascii码表只能存英文 数字 英文特殊符号, 无法存储其他语言文字
- 民用化之后,编码表不够用 对其他语言进行补充 unicode 万国码
- utf-8 utf-16
- 中文在编码表范围 u4e00-u9fa5
编码表作用
- 用于字符串比较
+ 一位一位比,每一位按照编码表比
+ ‘a’ > ‘A’
+ ‘21’< ‘3’
+ ‘2a’ ‘2A’
- 用于字符串的方法(不常用)
charAt(索引)
- 按照索引找到字符
charCodeAt(索引)
- 按照索引找到字符,在找字符对应编码
字符串常用方法
- 字符串.indexOf(字符) 找到返回索引,找不到返回-1
- 转大写 字符串.toUpperCase()
- 转小写 字符串.toLowerCase()
字符重要的方法 进行字符串裁剪
- 裁剪不会改变原字符串 会返回一个新字符串
- 字符串.substr(开始索引,截取的个数)
- 字符串.substring(开始索引,结束的索引) 包含开始索引 不包含结束索引
既可以裁剪数组,也可以裁剪字符串
- 字符串.slice(开始索引,结束的索引) 包含开始索引 不包含结束索引
- 索引可以写负数,负数就是从右往左数 从-1开始
检测数据类型 typeof
用法:typeof 数据、typeof(数据)
会返回当前数据的类型,返回的都是string类型
返回结果
- 数字类型 ‘number’
- 字符串类型 ‘string’
- 布尔类型 ‘boolean’
- undefined ‘undefined’
- null ‘object’
类型转换
转数值类型
转换方法
Number(数据)
- 把整个字符串当成一个整体转成number类型,如果里面有非数字的,都会转成NaN
parseInt(数据)
- 从字符串第一位开始,来判断是否是数字,如果是数字就保留,不是数字就结束,返回结果,无法识别小数点
parseFloat(数据)
- 从字符串第一位开始,来判断是否是数字,如果是数字就保留,不是数字就结束,返回结果,可以识别第一个小数点
parseInt() 和parseFloat() 的区别在于:
parseFloat() 所解析的字符串中第一个小数点是有效的,而parseInt() 遇到小数点会停止解析,因为小数点并不是有效的数字字符。 parseFloat() 始终会忽略前导的零,十六进制格式的字符串始终会被转换成0,而parseInt() 第二个参数可以设置基数,按照这个基数的进制来转换。
字符串 string
+ 字符串转数值,一般字符串是纯数字的用Number方法
+ 如果有非数字的用parseInt或者parseFloat
- 如果需要保留小数点用parseFloat
- 如果不需要用parseInt
其他数据类型转number都用Number方法
布尔 boolean
true 1
false 0
undefined
NaN
null
0
转字符串类型
方法:
- String(数据)
- 数据.toString()
+ 延伸用法 数据.toString(进制)
+ 针对于数值类型转成字符串,可以转换进制
要转换类型
- number
- boolean
- undefined
- null
注意:
1.所有类型转换成字符串都可以使用 String方法
2.null和undefined不能使用toString()
转布尔类型
方法:
- Boolean(数据)
number
+ 0 NaN 会转换成 false
+ 其他都是true
string
+ ‘’ “” 空字符串转换成false
+ 其他都会转成 true
undefined
+ false
null
+ false
NaN && isNaN
NaN与任何数据都不相等 包括自身
在其他类型转number时候,无法以数字的方式显示,只能转换类型
+ 代表是一个非数字的数值类型
+ not a number
+ isNaN(数据) 得到布尔值
- 这个数据是一个非数字吗?
- 如果数据是一个数字 false
- 如果数据是一个字符串
- 纯数字 false 先把字符串转换成number(不需要我们自己去转,js自动转换)
- 非纯数字 true
运算符
数学运算(算术运算)二元运算
+ - * / %(取余)
NaN和任何数据进行运算都是NaN
其他任何运算都会把左右两侧数据转换成number在进行运算
加法运算时左右有一个是字符串时候,另一个也会转成字符串在进行拼接
比较运算符
+ > < >= <= ==(等于) !=(不等于) =(全等) !(全不等)
赋值运算符
= += -= *= /= %=
a+=b --> a = a+b 将运算符左侧加上右侧的值再赋值给左侧
逻辑运算符
+ && 并且(与)
+ || 或者
+ ! 非(取反)
+ 条件1 && 条件2
+ && 必须条件1和条件2都为真的得到结果才为真
+ || 必须条件1和条件2都为假的得到结果才为假
+ !条件 如果条件为真变成假 条件为假变成真
+ 短路问题
1. js惰性导致的
2. && 左侧条件为假 不执行右侧表达式 false
3. || 左侧条件为真 不执行右侧表达式 true
一元运算符(自增和自减)
后置
- a++ --> a=a+1
- a-- --> a=a-1
前置
- ++a --> a=a+1
- --a --> a=a-1
不管是前置还是后置,都会将本身加一或者减一
区别:当发生赋值的时候,前置会先自增在赋值,后置会先赋值再自增
三元运算符(三目运算)
语法:
条件 ? 表达式1 : 表达式2
+ 条件为真的时候 执行表达式1,不会执行表达式2
+ 条件为假的时候 执行表达式2 不会执行表达式1
选择语句 分支语句 判断语句
单分支语句
if(条件){
表达式
}
+ 只有条件满足的时候才会执行表达式
+ 条件不满足不会执行表达式
双分支语句
if(条件){
条件满足执行
}else{
条件不满足执行
}
多分支语句
if(条件1){
条件1满足执行的语句
}else if(条件2){
条件2满足执行的语句
}else if(条件3){
条件3满足执行的语句
}
…
else{
以上所有条件都不满足执行的语句
}
+ else if个数根据情况而定,没有固定个数限制
+ else 可以不写
+ if 不可以不写 必须要写
switch…case语句
switch(值){
case 场景值1:
语句1;
case 场景值2:
语句2;
case 场景值3:
语句3;
…
default:
默认语句;
}
值和场景值匹配是全等匹配 === 值相等 && 类型相等
- switch语句具有穿透性: 只要匹配上之后,后面所有case都会执行
- 阻止穿透效果 加break 在每一个case后面加上break
区分switch和if语句
+ 如果条件是一个范围的话 优先选择 if语句实现
+ 如果条件是一个固定值 优先选择switch
+ switch有默认穿透效果
循环语句
定义: 重复执行一段代码
组成条件:
1. 初始化状态
2. 条件判断
3. 循环体代码
4. 自身状态变化
语法:
1. while
2. do…while
3. for(常用 90%)
执行的步骤:
1. 执行初始化状态
2. 执行条件判断 如果条件满足执行3, 如果不满足就结束循环
3. 执行循环体代码
4. 自身状态变化
5. 回到第二步继续执行
注意事项
- 必须要有状态变化,否则会出现死循环
while循环
初始化条件
while(条件判断){
循环体代码
自身状态发生变化
}
do…while循环
初始化条件
do{
循环体代码
自身状态变化
}while(条件判断)
while循环和do…while区别
- 循环体代码第一次执行的时候
- while会先判断条件是否满足,如果满足就执行,不满足一次不执行
- do…while会先执行一次循环体代码,再进行判断
- 导致如果初始化条件就不满足,while循环体代码一次都不会执行,但是do…while会执行一次
for循环
for(初始化条件;条件判断;自身状态变化){
循环体代码
}
循环里的关键字
continue 结束本次循环,进入下一次循环
break 跳出当前整个循环
break和continue只能控制当前自己这一层循环
总结:JavaScript中有三种循环结构 分别是 while、do-while、for 三种循环在大多数情况下是可以互换的 while循环先判断循环条件,若条件满足则执行循环体内语句 do-while先执行一次循环体内语句,然后判断循环条件,若条件满足则再次执行循环体内语句 for语句一般用来循环可明确循环次数的情况,首先初始化变量,然后判断条件,若满足条件执行循环体,循环变量修正、然后再判断循环条件。
引用数据类型(复杂数据类型)
函数(方法)
在js里面函数是第一公民
作用: 封装
含义:
将一段代码放到一个盒子里面,给盒子取一个名称,在我们需要执行这段代码的时候,根据这个名称,把代码拿出来执行
定义(声明)
声明式定义
+ function 关键字
+ 函数名
+ () 小括号
+ {} 花括号
```
function 函数名(){
// 盒子
}
```
赋值式定义
```
var 函数名 = function(){
// 盒子
}
调用函数
- 函数名()
函数定义阶段完成的事情
- function js会开辟一块空间 得到一个地址
- 将这个地址赋值给这个函数名
- 将代码以字符串方式存储到这个空间里面
函数调用阶段完成的事情
- 会根据函数名存储的地址找到这个空间
- 把这个空间里面代码拿出来执行
参数
- 在函数小括号里面写的数据被称为参数
- 写在定义函数小括号里面参数被称为形式参数 简称 形参
- 一般形参是一个变量
- 写在调用函数小括号里面参数被称为实际参数 简称 实参
- 一般实参是一个具体数据
- 实参实际上是给形参赋值
- 形参和实参个数情况:
1. 形参个数大于实参个数
- 多余形参的值为undefined
2. 形参个数等于实参个数
- 实参会给形参一一赋值
3. 形参个数小于实参个数
- 多余的实参没有任何作用
函数的返回值
一个函数调用完成之后得到的一个结果
- 默认的函数调用之后它的返回值是undefined
- 如果我们想要函数执行完成有一个返回值,用return 返回值
- return 之后的代码不会执行
函数不定参数
定义函数的时候不知道调用函数传递实参个数
每一个函数的内部都有一个类数组叫arguments,记录了传入实参信息
函数的优点
-
代码更加简洁
-
可以高度复用 有利于维护
预解析(声明提前)
提前执行代码
+ java *.java --> *.class --> 运行
+ javascript *.js --> 预解析 --> 在浏览器里面运行
+ js在运行之前会通读整个js代码 通过的过程就是预解析的过程,这个过程我们不需要自己写代码或者利用软件去实现,浏览器会自动执行
+ 我们需要关注就是预解析做了哪些事情,对我们有哪些影响
预解析做了两个事情:
1. 会将带有var关键字声明的变量提前执行,造成影响:我们可以在定义变量之前使用这个变量,使用这个变量得到结果是undefined 只会将变量的声明提前,不会将变量的赋值提前
2. 只会将声明式定义函数定义提前,会知道这个函数是一个可执行函数
造成的影响:
+ 声明式的函数在定义之前可以调用
+ 赋值式的函数不可以在定义之前调用
补充一些方法
+ Math.random() 随机得到[0-1)之间的数
+ Math.PI π 圆周率
+ toFixed(n) 保留n位小数 得到结果是字符串
作用域
一个数据起作用的范围(变量,函数…)
形成:由于函数的原因
分类:
1.全局作用域 window
+ 不被任何函数包裹的
+ 在全局声明(定义)的变量被称为全局变量
+ 全局变量可以在任意的位置使用
2.局部作用域
+ 函数内部
+ 在函数内部声明(定义)的变量被称为局部变量
+ 局部变量只能在对应函数内部使用,不能够在全局作用域或者其他局部作用域使用
变量访问(使用)规则
- 使用变量的时候规则
- 就近原则
- 一个作用域里面使用变量的时候会优先在自身里面查找,如果自身有,就使用自身。
- 如果自身作用域里面没有,会向上一级作用域查找,上一级有的话就使用,没有的就继续往上查找
- 一直找到全局作用域,全局作用域里面有就使用,没有的话就会报错,报这个变量未定义
变量的赋值规则
- 给变量赋值的时候规则
- 一个作用域里面给变量赋值的时候,会优先找自身作用域里面是否定义过这个变量,如果定义了就给自身作用域里面变量赋值,不会给上一级作用域里面变量赋值
- 如果自身作用域里面没有定义这个变量,会向上一级作用域查找是否定义了这个变量,如果有定义,就给上一级作用域里面变量赋值,如果上一级作用域也没有定义,会继续往上查找
- 一直找到全局作用域,如果全局有定义过这个变量,就给全局作用域里面这个变量赋值,如果全局都没有定义过这个变量,会在全局自动定义这个变量,然后再给全局的这个变量赋值
几个特殊的函数
- 匿名函数
- 自执行函数
- 递归函数
+ 函数自身调用自身
- 工厂函数
- 构造函数
对象Object
js第二重要的存数据类型
对象是一种特殊的数据类型,可以用来存储键(key)值(value)对 的数据
定义(创建)
1. 字面量
- var obj = {}
2. 内置构造函数: js里面自带
- var obj = new Object()
给对象添加属性(存储数据)
1. 点语法 obj.属性名(key) = 属性值(value)
\2. 下标法 obj[‘属性名’] = 属性值
获取对象里面的数据
-
点语法 obj.key 能够获取 value
-
下标法 obj[‘key’] 能够获取 value
区分:
当对象的key是一个变量的时候,只能使用下标语法
遍历(将所有的都访问一遍)对象里面的数据
- for(var key in 对象名){} for…in语法
- for…in 可以遍历一个对象,循环去读取对象里面的key
- {a: 1, b:2, c:3}
- 第一次 获取 a
- 第二次 获取 b
- 第三次 获取 c
- 结束循环
删除对象里面的某一个属性
- delete obj.key 删除整个键值对
修改对象里面某一个属性
重新赋值
数组
含义: 有序的数据集合
有序: 下标(索引) 从0开始的
创建数组
1. 字面量 var arr = []
\2. 内置构造函数 var arr = new Array()
数组里面存储数据的条数 --> 数组长度
- arr.length
添加数据
1. 创建的时候填写数据
- var arr = [2,3,4,454,5,321]
- var arr1 = new Array(21,32,43,45)
2. 通过下标来添加数据
- arr[下标] = 数据
- 下标决定了数组长度,未添加数据的下标位置对应是一个空数据
3. 通过方法来添加数据
- unshift() 先数组的开头追加一个数据 unshift()执行后返回值为新数组的长度
- push() 向数组末尾追加一个数据
取出数据
1. 可以通过下标取用
- arr[index] index下标 索引
2. 通过方法来获取数据
- shift() 从数组开头输出一个数据
- pop() 从数组结尾输出一个数据
遍历数组 取出数组里面所有数据
1. 利用for循环 从0开始 - 数组长度-1
2. 利用for…in循环
修改数组里面某一项数据
1. 通过下标赋值覆盖
arr[index] = 重新赋值
2. splice(从哪开始删除,删几个,插入几个)
删除数组里面某一项数据
- splice(开始删除数据的索引,删几个) 从开始删除几个
- splice(开始删除) 从开始一直删除到最后
- 删除会改变原数组
拼接数组(合并数组)
- concat(要合并数组)
判断数组里面是否包含某个数组
- arr.indexOf(数据) 如果有的话返回对应数据下标,如果没有返回-1
数组的去重
- 将数组里面相同数据只保留一份
- 思路:
+ 新建一个空数组
+ 遍历原数组,将原数组里面每一项取出
+ 判断新数组是否包含这个取出来数据,只有新数组里面没有这个数据才添加进去
+ 得到新数组就是去重后的原数组
数组的排序
- 按照从大到小 从小到大 排列数组里面的数据
- 冒泡排序
+ 大数沉底法
+ 相邻两个数据两两比较,如果前面数大于后面数,前后交换位置
数组方法
+ sort() 改变了原数组
+ reverse() 反转数组 改变原数组
字符串和数组的相互转换
+ 把字符串拆分成数组
- 字符串.split(分隔符)
+ 把数组拼接成字符串
- 数组.join(拼接符)
值传递和引用传递
- 在js里面数据存储方式有两种: 栈和堆
- 基础的数据类型值就直接存在栈里面
- 复杂的数据类型值不是存在栈里面,存在堆里面的
- 基础数据类型赋值是值传递的过程
+ 一个变化另一个不会变
- 复杂数据类型赋值是地址(引用)传递的过程
+ 一个变化另一个也会变
数组遍历 获取数组每一项
- 先获取索引,在获取每一项
+ for循环
+ for…in
- 数组的方法
+ forEach(function(item,index,arr){})
- 必须要传一个函数当成一个参数
- item 代表数组每一项
- index 代表数组索引
- arr 原数组
+ map(function(item,index,arr){})
- 必须要传一个函数当成一个参数
- item 代表数组每一项
- index 代表数组索引
- arr 原数组
返回一个计算后的新数组
- 需要将数组里面每一项都进行运算,运算之后得到一个新数组
+ filter(function(item,index,arr){})
- 必须要传一个函数当成一个参数
- item 代表数组每一项
- index 代表数组索引
- arr 原数组
返回一个过滤后的新数组
- 需要将数组里面每一项进行过滤,得到一个过滤后的新数组
- 去重
js的内置对象
- 内置 js本身自带
- Math 凡是和数学有关运算
属性就是一个具体数据
方法就是一个函数
Math对象的属性
- Math.PI 圆周率
- Math.E 自然数e
Math对象的方法
- 生成随机数
+ Math.random()
- 数学运算取整
+ parseInt 直接去除小数位 得到整数
+ 向上取整
- Math.ceil(数) 5.1 5.99 5.0001 6
+ 向下取整
- Math.floor(数) 5.1 5.99 5
+ 四舍五入取整
- Math.round(数) 5.4 5 5.9 6
- 其他数学运算
+ 求绝对值
- Math.abs(数) -5 5
+ 求最大数
- Math.max(数,数…)
+ 求最小数
- Math.min(数,数…)
+ 求幂数
- Math.pow(m,n) m的n次方
js的内置构造函数
- new Object() new Array() new String() …
- new Date()
- Date是一个js里面内置的构造函数 和日期相关的
- 获取是本地时间,当前计算机的时间,这个时间用户是可以修改的
使用步骤:
1. 利用new Date得到一个日期对象
2. 利用这个日期对象来获取年月日 时分秒 星期
- 获取年份
+ date.getFullYear()
- 获取月份
+ date.getMonth()
+ 月份是从0开始的,正常获取月份需要加1
- 获取日期
+ date.getDate()
- 获取小时
+ date.getHours()
- 获取分钟
+ date.getMinutes()
- 获取秒数
+ date.getSeconds()
- 获取星期
+ date.getDay()
+ 从0开始 0代表星期天 1星期一…
定时器
- 每隔多少毫秒多次执行一段代码
+ setInterval()
- 延迟多少毫秒执行一段代码
+ setTimeout()
获取毫秒数
- date.getTime()
+ 获取是当前时间距离标准时的差值 是一个毫秒数 这个差值还有别名 时间戳
- 初始化的时间,格林尼治时间,标准时 1970-01-01 00:00:00
- 用于时间计算
- ‘2021-07-30 14:10:00’
- ‘2022-02-01 00:00:00’
严格模式
如何开启
+ “use strict”
+ 一旦代码里面写了上面这句话,后面所有代码检测都是按照严格模式
- 注意
+ *变量声明的时候必须要写var*
+ *定义函数的时候形参不能够重名*
+ 函数内部没有this
BOM
+ 所有的BOM内容都是存到 window 对象
+ 弹窗
- alert()
- prompt()
- confirm()
+ 地址栏 window.location location
- location.href 获取地址栏完整地址
- location.href = 路径 跳转到这个路径
- location.protocol 协议
- location.hostname 域名
- location.port 端口号
- location.pathname 路径
- ** location.search 请求参数 **
- location.hash 哈希值
- 浏览器地址里面只能识别ACSII码表上面内容,如果是非码表上面的会自动转码
- 转码 encodeURI()
- 解码 decodeURI()
网页中一个地址组成
https://www.baidu.com:443/s?wd=11%E6%9C%88%E4%BB%BD%E6%98%AF%E4%BB%80%E4%B9%88%E6%98%9F%E5%BA%A7&rsv_spt=1&rsv_iqid=0xae1b79560008a219&issp=1&f=3&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=ts_0&rsv_sug3=3&rsv_sug1=2&rsv_sug7=100&rsv_sug2=1&rsv_btype=i&prefixsug=11&rsp=0&inputT=1462&rsv_sug4=1823#thrid
- 协议 http:// https:// file://
- 域名 www.baidu.com
- 端口号 hhtp 80 https 443
- 路径 /s
- 请求参数
```
?a=1&b=2&c=2
```
- 哈希值 # 后面值就是哈希值
封装一个获取地址栏请求参数方法
- ‘?a=1&b=2&c=2’ —> {a:1,b:2,c:3} location.search
- getQueryString(‘a’) // 1
js跳转 打开新页面方式
- location.href = 地址
- location.replace(地址)
- window.open(地址)
js的刷新当前页
- location.reload()
历史记录 history
- 获取历史记录长度
+ history.length
- 进入下一页
+ history.forward()
- 返回上一页
+ history.back()
- 前进几页后退几页
+ history.go(number) 当number为正数 前几几页 当number为负数 后退几页
+ history.go(0) 相当于刷新
navigator 浏览器的说明书
- userAgent 获取浏览器版本信息
+ 谷歌 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36
+ IE11 Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko
+ IE9 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)
+ IE8 MSIE 8.0
+ IE7 MSIE 7.0
- 封装一个检测浏览器版本的方法,主要用来区分IE和其他浏览器 并且区分出IE10-具体版本
BOM操作元素
操作元素的位置(偏移量)
- 元素左上角相对于浏览器左上角的距离 这个距离是有两个方向 left top
- 获取元素的位置
+ 元素.offsetLeft
+ 元素.offsetTop
+ 操作元素的尺寸(大小)
- 元素的尺寸其实就是元素的宽度和高度
- 内容 getStyle()
- 内容+填充区(padding)
+ 元素.clientWidth
+ 元素.clientHeight
- 内容+填充区+边框
+ 元素.offsetWidth
+ 元素.offsetHeight
DOM操作元素
- document object model 文档对象模型 网页元素相关
- 改变网页元素尺寸 位置 颜色…
- document 是整个文档
- 获取网页中的元素
- 根据某个标签(元素)的id
+ document.getElementById(id名称)
- 根据类名
+ document.getElementsByClassName(类名)
- 根据标签名
+ document.getElementsByTagName(标签名)
- 根据css选择器来获取
+ document.querySelector(css选择器) 获取匹配的第一个
+ document.querySelectorAll(css选择器) 获取匹配所有元素
- 操作元素 获取 设置
- 操作元素的内容
+ 获取
- 文本内容 innerText
- 所有内容(包含标签) innerHTML
+ 设置
- 文本内容 innerText=‘内容’ 不能够识别里面的标签,会把标签当成一个文本
- 所有内容 innerHTML=‘内容’ 识别里面的标签
- 操作元素的样式
+ 获取
- 元素.style.css属性 只能获取元素的行内样式,无法获取内部或者外部的样式
- 获取非行间样式
- getComputedStyle(元素).css属性
+ 设置
- 元素.style.css属性 = css属性值
- css属性-改成小驼峰
- 设置的样式是行内样式
- 操作元素的属性
+ 获取
- 元素.getAttribute(属性名) 返回属性值
+ 设置
- 元素.setAttribute(属性名,属性值)
+ 移出
- 元素.removeAttribute(属性名)
- 特殊属性 class
+ 获取类名
- 元素.getAttribute(‘class’)
- 元素.className
- 元素.classList
+ 设置类名
- 元素.setAttribute(‘class’, ‘类名’)
- 元素.className = ‘类名’
- 元素.classList.add(类名) 加上类
- 元素.classList.remove(类名) 移出类
DOM节点
+ 整个html页面就是一颗dom树
+ 每一个页面里面的标签都是dom树上面的节点
+ 类型(节点分类)
1. 标签 元素节点
2. 文字 文本节点
3. 属性 属性节点
4. 注释 注释节点
已知父节点获取子节点
+ 父节点.childNodes 获取里面所有的节点
+ 父节点.children 获取里面所有的元素节点
+ 父节点.firstChild 获取第一个子节点
+ 父节点.firstElementChild 获取第一个元素节点
+ 父节点.lastChild 获取最后一个子节点
+ 父节点.lastElementChild 获取最后一个子元素节点
已知一个节点获取相邻节点
+ 已知节点.previousSibling 前一个相邻节点
+ 已知节点.previousElementSibling 前一个相邻元素节点
+ 已知节点.nextSibling 后一个相邻节点
+ 已知节点.nextElementSibling 后一个相邻元素节点
已知子节点获取父节点
+ 子节点.parentNode
节点的属性
+ nodeType 元素节点 1 属性节点 2 文本节点 3 注释节点 8 可以利用来判断节点
+ nodeValue 元素节点 null 文本节点 文本内容 注释节点 注释内容
+ nodeName 元素节点 标签名大写 tagName
属性节点
+ 元素节点里面的属性和属性值
+
+ 获取属性节点
- 先获取元素节点
- 元素.attributes 获取里面所有属性节点
DOM操作
+ 包含对网页中节点的创建、添加节点、修改节点、删除节点、克隆节点(元素节点)
+ 创建一个一个节点
- 创建一个元素节点
- document.createElement(tagName)
- 创建一个文本节点
- document.createTextNode(文本内容)
+ 添加
- 在父节点最后添加一个子节点
+ 父节点.appendChild(子节点)
- 往父节点某一个子节点前面添加新节点
+ 父节点.insertBefore(新节点, 已存在节点)
+ 修改
- 修改当前节点里面的内容
+ 使用innerText或者innerHTML
- 替换节点
+ 父节点.replaceChild(新节点,老节点)
+ 删除
- 在父节点下面删除某个子节点
+ 父节点.removeChild(要删除的节点)
+ 克隆 clone
+ 已存在节点.cloneNode() 只会克隆当前节点,不会克隆子节点
+ 已存在节点.cloneNode(true) 会克隆子节点
事件
+ 绑定事件的方式
- 事件源.on+事件类型 = 事件处理函数
+ 注意点
- 一个事件源可以绑定多个类型的事件
- on绑定方式: 一个事件源同一事件类型不能绑定多个处理函数
+ 常见的事件类型
- 鼠标事件
- click 单击
- dblclick 双击
- mouseover 移入
- mouseout 移出
- mousemove 移动
- mousedown 鼠标按下
- mouseup 鼠标抬起
- mousewheel 鼠标滚动
- scroll 滚动条位移
- 键盘事件
- keydown 按下
- keyup 抬起
- 浏览器事件
- 初始化时间 load
- 尺寸变化 resize
- 表单事件
- 提交事件 submit
- 输入事件 input
- 值变化 change
- 获取焦点 focus
- 失去焦点 blur
+ 鼠标滚动事件
- mousewheel 事件源是window
+ 如何获取鼠标滚动方向
- 根据 event.wheelDeltaY 值的正负来判断
- scroll 事件源是 哪个元素具有滚动条
+ 获取滚动条滚动高度(页面卷去的高度)
- scrollTop
- docuemnt.body(body) document.documentElement(html)
- 区分兼容性:
\1. 页面有没有doctype
+ 有doctype document.documentElement.scrollTop(html)
+ 没有doctype docuement.body.scrollTop(body)
+ 设置滚动条高度
- document.body.scrollTop = 高度
- document.documentElement.scrollTop = 高度
- 两个一起设置,因为有兼容性,如果只设置一个可能会不生效
+ 获取滚动条滚动宽度
- scrollLeft
- 区分兼容性
+ document.documentElement.scrollLeft || document.body.scrollLeft
+ 设置滚动条宽度
- document.body.scrollLeft = 宽度
- document.documentElement.scrollLeft = 宽度
+ 浏览器事件 window
- 初始化事件 load
+ 网页里面所有的资源加载完成
- 尺寸变化 resize
+ 网页宽度和高度发生改变时触发
- 如何获取网页的宽度和高度
- window.innerHeight
- window.innerWidth
- 获取屏幕分辨率的宽度和高度
- window.screen.width
- window.screen.height
+ 事件对象 event
+ 获取event两种方式
- 每一个事件处理函数内部都有一个事件对象 event IE低版本不支持
- 每一个事件处理函数里面第一个参数默认就是事件对象 都可以兼容
+ 兼容性获取方法
- var event = window.event || e
+ event它是一个对象,它记录了当前事件的详细信息(坐标,点击源…)
+ 关于event的三个坐标
- offsetX offsetY
+ 鼠标相对于事件源上面的坐标 鼠标位置相对事件源左上角的x,y
- clientX clientY
+ 鼠标相对浏览器的坐标 鼠标位置相对于浏览器左上角的x,y
- pageX pageY
+ 鼠标相对于页面的坐标 鼠标位置相对页面左上角的x,y
- 当页面没有滚动条的时候,client和page相同, 当有滚动条,两者不同
+ 键盘事件
- keydown 按下
- keyup 抬起
- 事件源是window
- 判断按下哪个按键根据 event.keyCode
- 按下enter自动提交表单 13
- 空格键 32
- 判断组合键
- event.ctrlKey
- event.altKey
- event.shiftKey
- 当这几个键按住不放再按其他键,以上属性值为true,单独按下值为false
+ 表单事件 form
- 表单作用就是提交数据
- 表单name属性必须要加,他是提交给后端的字段名
- 表单里面的action就是后端给的提交地址
- 表单里面的method就是提交方式 get post
- 如果一个按钮写在表单里面,没有写类型 type 默认是submit
- submit 表单提交时触发的事件 事件源 就是这个表单
- 表单元素(表单控件) 快捷获取方式 表单.name
- 表单提交事件用于表单验证
+ 首先阻止默认的表单提交 event.preventDefault() 阻止默认事件
+ 进行验证
- 验证通过 手动提交表单 表单.submit
- 验证失败 提示用户
+ 表单的输入事件 input
- input文本类型 textarea 可以当成input事件的事件源
- 在控件里面输入的时候,每输入一次,事件就会触发一次
+ 表单控件值value变化事件 change
- 当控件的值变化了,而且光标失去了焦点才会触发change事件
+ 光标失去焦点
- blur
- 不会关注值变化 只要失去焦点就会触发一次
+ 光标获取焦点
- focus
事件绑定方式
+ on绑定方式
- 事件源.on+事件类型 = 事件处理函数
- 同一个事件源可以绑定多个事件类型
- 同一个事件源同一个事件类型只能绑定一个事件处理函数
+ 用事件监听的方式绑定事件
- 事件源.addEventListener(事件类型,事件处理函数)
- 同一个事件源同一个事件类型可以绑定多个事件处理函数
- 取消监听
+ 事件源.removeEventListener(事件类型,事件处理函数)
- 兼容性问题
js兼容性问题: 有几种情况
- 获取滚动高度 scrollTop
- 根据doctype不同 获取方式不同 有效是具体高度 无效是0
- document.body.scrollTop || document.documentElement.scrollTop
- 获取event
- window.event
- IE低版本无法识别 window.event获取到的是undefined
- window.event || e(事件处理函数默认第一个参数)
- 事件监听
- IE无法识别addEventListener,直接报错 它使用的是attachEvent
- 事件源.attachEvent(on+事件类型,事件处理函数)
- 区分浏览器 navigator.userAgent IE低版本 ‘MSIE’
- if(navigator.userAgent.indexOf(‘MSIE’) !== -1){//就是IE低版本} else{}
- 获取css样式
- 如果是行内 用事件源.style.css属性
- 如果是非行内
+ getComputedStyle(事件源).css属性 非IE
+ 事件源.currentStyle.css属性 IE
事件执行机制
- 事件执行的顺序 事件传播的方向
- 当多个元素嵌套,并且绑定相同的事件类型,这时候他们事件执行先后顺序被称为事件执行机制,也被称为事件传播
- 谷歌认为事件传播方向应该有用户触发事件的元素向上传播 一直传播到window
- 事件传播机制:冒泡机制
- IE认为事件传播方向应该是由外层的window向下传播 一直到触发事件的元素
- 事件传播机制:捕获机制
- 事件源.addEventListener(事件类型,事件处理函数, 事件传播方式) 默认机制是冒泡机制 默认的值是false 如果想要它是捕获机制 改为 true
事件委托
- 委托:自己无法完成某个事情,需要请求帮人的帮忙
- 事件委托: 某一个元素自己无法绑定这个事件,需要给别人绑定事件,来完成我要实现功能
- 使用场景: 当某个元素动态生成的,无法获取到这个元素,也就无法绑定这个事件,这时候给这个元素的页面已存在父元素绑定一个同类型事件,点击子元素也会触发父元素事件,再根据点击位置来判断时候点在子元素上面来实现功能
- event.target 目标元素
阻止默认事件
有一个默认行为,但是我们不需要这个默认行为
- 表单提交
+ 阻止默认事件 默认提交事件 做表单验证
+ 在表单sumbit事件里面
- a链接点击跳转事件
- event.preventDefault() 非IE
- event.returnValue = false IE
阻止冒泡
- 事件执行非IE浏览器有一个冒泡机制
- event.stopPropagation() 非IE
- event.cancelBubble = true IE
正则表达式 RegExp 复杂数据类型
+ 含义: 规则表达式 主要用于验证字符串是否符合规则的
+ 用途:
- 表单验证
- 字符串某些方法 替换(敏感)
+ 创建一个正则表达式
- 字面量创建 var reg = /正则表达式/
- 内置构造函数 var reg = new RegExp(正则表达式式)
+ 检测字符串是否符合规则的方法
- 正则表达式.test(字符串)
+ 字符串满足正则表达式返回true
+ 字符串不满足正则表达式返回false
+ 空字符里面是没有任何内容的,不包含任何内容
+ /\s/ /\S/ 检测字符串里面是否包含小写s 或者大写 S 前提是你们有内容
+ 正则表达式组成部分
- 元字符
+ 代表一类的字符串的符号
+ \d 代表数字
+ \D 代表非数字 只要不是数字都可以
+ \w 代表字母数字下划线
+ \W 代表非数字字母下划线 只要不是数字字母下划线都可以
+ \s 代表空白字符 (空格 制表符 换行)
+ \S 代表非空白字符串 只要不是空格 制表符 换行都可以
+ . 代表非换行的任意字符 除了换行之外的都可以
+ \ 代表转义字符
- 转义:转换意义
- 把一个有意义的东西变成它自己 . .
- 把一个没有意义的东西变成有代表意义 d \d
- 边界符
+ 代表正则表达式边界的
+ ^ 以什么开头
+ $ 以什么结尾
- 限定符
+ 限制字符串里面某个字符出现的长度
+ * 代表出现次数最少是0次 可以出现也可以不出现,出现不限制次数[0-正无穷]
+ + 代表至少出现一次 [1-正无穷]
+ ? 代表出现[0-1] 最多只能出现一次
+ {m} 代表出现m次
+ {m,} 代表至少出现m次 [m,正无穷]
+ {m,n} 代表最少出现m次最多出现n次 [m,n]
- 特殊字符
+ () 代表组的概念
+ | 或者关系
+ [] 代表一个字符集合
+ -
+ [^] 反字符集
+ ()一般和|连用代表一组里面可能有多重情况 (qq|sina|163) (com|cn|net) 代表某些特定的几种情况
+ [] 一般和 - 连用 代表一个范围
ES6
+ 之前所有的javascript内容都是es5 ecmascript 5
+ 网景 javascript IE JScript
+ 欧洲计算机制造商协会 ECMA ecmascript标准
+ es1
+ es2
+ es3
…
+ es4草案 突然间新增很多前卫的内容 激进型的内容 被广大程序员和浏览器厂商不能接收
- 没有被通过,被搁置
+ 在es3的基础上 发了es3.1(es5)
+ 版本有大的变化 es5 —> es6 (阮一峰)
+ 重启es4草案 发布了一个es2015 (es6)
+ es2016 es7
+ es2017 es8
+ es6 es7 es8 但是不能够被所有浏览器接收,不能够运行在所有的浏览器上面
+ 运行的环境在谷歌浏览器最新版,在IE或者谷歌低版本上面会报错
+ 一般项目里面都是es6代码,通过有一个babel转换成es5代码
+ es6他使用起来只会比es5简单
let 和 const
声明(定义)
- var 变量名;
- 变量名 = 数据;
- var 变量名 = 数据;
let和const两种声明变量新的方式
const
- var定义的是变量 能够改变的数据
- const定义的是常量 不允许改变的数据
- const 定义变量是不允许被改变的,一般常量名推荐大写
- 不允许改变针对的是基础数据类型 值变化报错
- 如果是一个引用的数据的类型 array object 除非它的地址变化了会报错,如果只改变他的数据,是不会发生的变化 地址变化报错
let
- 作用域
1. 全局作用域: 不被任何函数包裹的
2. 局部作用域: 被函数包裹
3. 块级作用域: 被{}包裹的
- 变量
1. 在全局作用域里面用var声明(定义)变量被称为全局变量
2. 在局部作用域里面用var声明(定义)变量被称为局部变量
3. 在块级作用域里面用let声明(定义)变量被称为块级变量
- 使用注意事项:
1. 块级变量只能在当前块级作用域里面使用,不能在其他地方使用
2. let没有变量提升,没有声明提前,var是有变量声明提升(预解析)
3. let会导致作用域死区(报错的) 如果块级里面有var声明过的变量,再使用let声明会导致作用域死区
+ 箭头函数
- 函数定义的方式两种 普通函数写法
1. 声明式定义 会触发预解析
2. 赋值式定义 一般用于时间绑定 box.onclick = function(){}
- 函数另一种写法
1. var fn = () => {}
2. var 函数名 = () => {函数体}
简易写法
\1. 如果函数内部代码只有一行并且要将这一行表达式结果返回
- var 函数名 = () => 表达式
\2. 如果函数参数只有一个,小括号可以省略不写,但是如果没有参数或者一个以上参数,小括号必须写
- var 函数名 = a => 表达式
解构赋值
- 就是快速的从对象或者数组中取出成员的一个语法方式
- 解构对象 {key:name,key1…} = obj
- 解构数组 [num,num1,num2…] = arr
展开运算符 …
- 主要用于数组和对象的合并
- 合并数组 var arr = […arr1,…arr2…] 数组里面重复项会保留
- 合并对象 var obj = {…obj1,…obj2…} 对象里面重复的key后面的会覆盖前面值
- 用于数组和对象的浅克隆(复制)
- 浅克隆 复制
- 复制一个clone对象或者数组,要达到一个变化另一个不会改变
模板字符串
+ 字符串 “” ‘’
+ 字符串的弊端
- 里面无法识别变量
- 无法换行写
+ 模板字符串使用是反引号 键盘esc下面 ``
+ 模板字符串里面可以识别变量 ${变量}
函数的默认值
+ 当函数的形参没有实参赋值的时候会有一个默认值
+ function sum(a=1,b=2){}
+ sum(10,20) a=10 b=20
+ sum(10) a=10 b=2
+ sum() a=1 b=2
函数的不定参数
+ 函数在定义的时候无法确定形参数量,只有在使用的时候才知道具体实参个数
+ 普通函数可以使用arguments或者 …变量名 不定参数写法
+ 箭头函数没有arguments只能使用不定参数写法
+ 不定参数只能写在函数参数的最后面
+ 把确定的参数放到前面,把不定参数放到后面
es5里面的this** 面试重点**
+ this指代当前 这个
+ 在事件处理函数 this指代(就是)事件源
+ 每一个函数内部都有一个this,但是this指向不同
+ 普通函数里面this指向看谁在调用这个函数,谁在调用,this就指向谁
+ 箭头函数里面没有this,他使用外层作用域里面的this
+ this怎么看?
- 普通函数看调用
- 箭头函数看定义
+ 手动去改变this的指向
- call()
- apply()
- bind()
- call apply bind都可以改变this的指向 将this指向到第一个参数
- call和apply 在改变的时候同时调用了这个函数 bind不会调用这个函数 返回一个新函数
- call调用函数传参,参数从第二个参数开始传递 sum.call(obj,参数1,参数2…)
- apply调用函数传参 第二参数是一个数组 数组里面每一项对应函数函数里面的参数 sum.apply(obj, [参数1,参数2…])
JSON
+ 是一种数据格式 也是一种文件格式 文件尾缀 *.json
+ 前后端数据交互准备
+ 页面分为静态页和动态页面 — 数据区分
+ json是前后端数据交互的一种数据格式
+ 这种数据格式任何语言都能够识别
格式要求:
1. 不可以在里面写注释
2. key和value必须用双引号包裹 除了value为boolean number null
3. 结束如果后面没有内容,不能有,
学会将json字符串和js的数据格式相互转换
- js数据格式 --> json字符串 前端发送数据9后端
+ var json字符串 = JSON.stringify(js数据格式)
- json字符串 --> js的数据格式 后端返回数据给前端
+ var js的数据格式 = JSON.parse(json字符串)
定时器
+ 间隔执行
- setInterval(()=>{}, 1000)
+ 延迟执行
- setTimeout(()=>{}, 1000)
面向对象 javascript 难点 重点 面试重点
+ OOP
+ 面向: 脸朝向 关注 关注对象
+ 编程思想:指导编程
- 面向过程 之前我们所有的代码都是面向过程 关注过程 关注每一步的实现
- 面向对象 关注对象 创建出来一个对象 利用这个对象来解决问题 封装
- 面向函数 关注函数
+ 吃面条
- 面向过程
- 买面粉
- 烧开水
- 和面
- 拉面
- 热锅烧油
- 煮面
- 吃面条
- 面向对象
- 找一个家面馆 叫一碗面
- 等着吃面
+ 面向对象 使用场景 一个功能多次或者在多个地方使用到了
什么是对象?
+ {key:value,key1:value1…}
+ 是否能使用点语法访问里面的属性
+ var obj = {username: ‘jack’}
- obj.username
创建对象
- 使用字面量和内置构造函数
- 如果创建多个对象的话 并给对象添加属性和方法 代码量重复 并且 代码冗余
- 使用工厂函数来创建对象
- 工厂函数: 写法和用法都和普通函数没有任何区别
- 区别在函数的作用 批量创建的
- 优点:不需要每创建一个对象都要添加属性和方法
- 缺点:
1. 第一个问题: p1.sayHi和p2.sayHi它的功能都是一样的使用的不是同一份
2. 第二个问题: 工厂函数里面需要手动去创建一个对象并且返回这个对象 能不能省略不写
3.使用自定义构造函数
- 内置(js自带)构造函数 new Date() new Array() new Object()…
- 自己定义一个这个函数 也用new来调用
- 解决了第二个问题
4.原型 prototype proto 两个下划线
- 每一个函数都会有一个属性叫prototype,他是一个对象,构造函数是一个函数,它也有
- 每一个对象都会有一个属性叫__proto__,它也是一个对象,利用构造函数new出来的得到是一个对象,它里面也有这个属性
- 构造函数new的过程被称为 实例化过程 得到对象(p1,p2)被称为实例化对象
- 每一个实例化对象的__proto__就是构造函数的prototype
+ p1.proto == person.prototype
+ p2.proto == person.prototype
- 解决第一个问题 公用方法的问题
- 将公共的方法
5.原型链
- 每一个对象里面都有一个__proto__属性就是对应它的构造函数的prototype
- 每一个对象的__proto__本身也是一个对象,所以他也有__proto__属性,这样的__proto__ 回组成一个链条被称为原型链 链条的顶端 构造函数 Object
对应Object的 prototype是null 原型的顶端就是null
- 每一个对象使用属性和方法的时候会优先在自身查找,如果自身没有往他的__proto__里面查找,如果有就使用,如果__proto__ 还没有往__proto__.proto 一直找到null
如果还没找到 属性的会得到undefined 方法直接报错
6.面向对象
- 创建出一个对象 给对象添加属性和方法 利用这个对象来解决问题
- 利用自定义构造函数的方式创建对象
- 在自定义构造函数内部通过this来添加属性 (属性是每一个实例不一样)
- 在自定义构造函数prototype上面添加方法(公用)
7.实现案例
- 面向过程 轮播图
1. 写样式
2. 克隆图片 插入 头部插入最后一张 尾部插入第一张 设置ul的宽度 (初始化)
3. 动态生成点 点的个数和图片张数对应
4. 添加左右箭头的点击事件
5. 考虑边界问题 回调函数判断边界
6. 加锁 保护点击过快的问题
7. 点击点跳转到对应图片
8. 实现输入移入停止轮播 移出自动轮播
- 面向对象
1. 在网上找一个轮播图的插件 swiper