JavaScript
ECMAScript
1.输出方式
console.log("output1")
document.write("output2")
alert("output3")
2.变量提升
console.log('变量提升',a) // 变量提升 undefined
var a,b,c = 10
3.数据类型
- 基础数据类型
- number
- string
- boolen
- undefined(声明变量,没有赋值,表示数据类型不确定)
- null(表示数据确定,用来释放对象)
- 引用数据类型
- object(引用数组类型赋值传递内存中的地址、操作时影响原有数据,基础数据类型传递的是复印件、不会影响原有数据)
- 判断数据类型:typeof
- string 转为 number: parseInt(只取整数部分),parseFloat(只取小数),不能转换返回 NaN
var d
console.log(d, typeof d) // undefined 'undefined'
d = null
console.log(d, typeof d) // null 'object'
4.运算符
console.log(undefined == null, undefined === null, NaN == NaN) // true false false
5.分支结构
6.循环结构
- break 跳出代码块或者循环
- continue 终止本轮循环,开始下一轮
7.String
- 返回下标对应字符
Str.chatAt(num)Str.charCodeAt(num)
let a = '1234567890987654321'
a.charAt(4) // '5'
a.charCodeAt(4) // 53
- 截取字符串
Str.substring(begin,end)Str.substr(begin,count)Str.slice(begin,end)
let a = '1234567890987654321'
a.substring(1,5) // '2345'
a.substr(1,5) // '23456'
a.slice(1,5) // '2345'
- 拼接字符串
Str + Str1Str.concat(Str1,Str2,....)
- 大小写转换
Str.toUpperCase()Str.toLowerCase()
- 查找字符串
Str.indexOf(要找的字符,begin)Str.lastIndexOf(要找的字符,begin)Str.search(要找的字符)Str.match(要找的字符)
let a = '1234567890987654321'
a.indexOf(3,0) // 2,index值,数字
- 分割字符串
Str.split('分隔符')
- 删除字符串两端空格
Str.trim()
- 替换字符串
Str.replace('旧的字符','新的字符')- search、match、split、replace常和正则搭配
- 是否包含''
Str.includes('字符')
- 是否以''开头,是否以''结尾
Str.startsWith('字符')Str.endsWith('字符')
- 异常捕获机制
- 前面代码有异常,也可让后面程序正常执行
try{
可能有问题的代码
} catch (error){
错误处理方式
}
8.Array
8.1数组遍历
- for
- for in:遍历数组的下标(index)或对象的属性(key)
- for of:遍历的是数组值,没有下标
- forEach:数组的方法,遍历数组值和下标
8.2 数组对象方法
- Arr.length
- 数组长度
- 获取长度
- 设置长度
- 数组长度
- Arr.push(值1, 值2, 值3,...), Arr.pop(), Arr.unshfit(值1, 值2, 值3,...), Arr.shift()
- 在数组末尾增加,返回增加后的数组长度,改变原数组;
- 在数组末尾删除,返回被删除数组元素,改变原数组;
- 在数组头部增加,返回增加后的数组长度,改变原数组;
- 在数组头部删除,返回被删除数组元素,改变原数组;
- Arr.join([分隔符])
- 数组转化为字符串,默认分隔符为‘,’
- Arr.indexOf(要查找的值, 查找的起始位置), Arr.lastIndexOf(要查找的值, 查找的起始位置)
- 查找数组元素
- 返回查找元素下标,没有返回-1
- 从前向后,从后向前
- Arr.includes(要查找的值, 查找的起始位置)
- 查找数组元素
- 有返回true,没有返回false
- Arr.slice(begin,end)
- 截取数组
[begin,end)- 省略 end,截取到末尾
- 省略 begin 和 end,对原有数组复制
- Arr.splice(开始位置下标, 删除个数, 增加值1, 增加值2,...)
- 增/删/改数组,返回被删除数组元素,改变原数组
- 增 Arr.splice(开始位置下标, 0, 增加值1, 增加值2,...)
- 删 Arr.splice(开始位置下标, 删除个数)
- 改 Arr.splice(开始位置下标, 删除个数, 增加值1, 增加值2,...)
- Arr.contact(值1, 值2, 值3,...)
- 返回拼接后数组,不改变原数组
- Arr.reverse()
- 返回翻转后的数组,改变原数组
- Arr.sort(参数)
- 对数组中元素排序,改变原数组
- 无参数时,按字母和升序将值作为字符串进行排序
- Arr.map((currtVaule,index,arr)=>{})
- 不改变原数组
- 返回一个新数组,数组中的元素为原始数组调用函数处理后的返回值 不会对空数组进行检测
- Arr.filter((currtVaule,index,arr)=>{})
- 不改变原数组
- 返回一个新数组,数组中的元素为原始数组中符合条件的元素
- 不会对空数组进行检测
- Arr.find((currtVaule,index,arr)=>{}), Arr.findIndex((currtVaule,index,arr)=>{})
- 返回原始数组通过测试的第一个元素值
- 返回原始数组通过测试的第一个元素的下标
- Arr.some((currtVaule,index,arr)=>{}), Arr.every((currtVaule,index,arr)=>{})
- 检测数组中的元素是否有满足条件的,有的返回true,否则false
- 检测数组中的元素是否都满足条件 15.Arr.reduce((prev,currtVaule,index,arr)=>{}, 初始值), Arr.reduceRight((prev,currtVaule,index,arr)=>{})
- 接收一个函数作为累加器
- 从左到右将数组中的值开始计算,返回累加值
- 从右到左将数组中的值开始计算,返回累加值
- 初始值没设置时,第一次调用时,prev为数组的第1个元素,currtVaule为数组的第2个元素,index为数组的第2个元素的下标;
- 第二次调用时,prev为第一次调用的结果,currtVaule为数组的第3个元素,index为数组的第3个元素的下标
- 选择排序法
- 用数组的每个元素和他后面的元素作比较,如果符合条件则交换
9.Object
- 查、删
- obj.属性名 obj['属性名'/变量]
- delete obj.属性名
- 对象遍历
- for in
- Object.keys(obj)
- Object.values(obj)
- Object.entries(obj)
- Math
- Math.PI
- Math.ceil(num) 向上取整
- Math.floor(num) 向下取整
- Math.round(num) 四舍五入
- Math.pow(x,y) x的y次方
- Math.max(x,y,...) 最大值
- Math.min(x,y,...) 最小值
- Math.abs(num) 绝对值
- Math.sqrt(num) 平方值
- Math.random()
[0,1)的随机小数 - parseInt(Math.random() * (max + 1 - min) + min)
[min,max]的随机整数
- Date
10.函数
- 参数:形参、实参
- 定义函数时所使用的的参数为形参
- 调用函数时所使用的的参数为实参
- 值传递、地址传递
- 值传递为将具体数据(基本类型数据)的副本传递给对方,对方在操作时不影响原数据
- 地址传递为将引用类型数据的内存地址传递给对方,对方在操作时影响原数据 3.定义函数
- 函数声明,函数名称存储的是内存地址
function 函数名称(){ 函数体 }
- 函数表达式,变量名称存储的是内存地址
var 变量名称 = function(){ 函数体 }
- Function构建方法
var 变量名称 = new Function('形参1','形参2',...,'函数体')
- 区别:函数声明定义的函数可以在定义前调用,函数表达式定义和Function构建方法定义的不行。函数声明提升和变量声明提升不一样
- 全局变量、局部变量
- 如果局部变量和全局变量同名,要使用全局变量可以用 window.变量 或 this.变量,因为全局变量是 window 对象绑定的属性
- argument对象
- 函数内部的一个对象,用来管理函数被调用时传递过来的实参,伪数组,多用于实参个数不确定的情况
- argument.length 实参个数
- argument.callee 指向 argument 对象所在的函数,常与递归函数和匿名自执行函数结合使用
- 递归函数
- 一个函数内部调用了自己
funtion fn(){ fn(); }- 在使用递归函数时,一定要在某个时刻能够让函数不再调用自己,确保有“出口”
- 推荐在递归函数内部使用 argument.callee 属性来引用当前函数
- 回调函数,一个函数作为另一个函数的参数
- 匿名自执行函数,
(function(形参...){ 函数体 })(实参...)
11.call、apply
重定义this对象的值,以扩充函数的作用域
fn.call(借用者3,参数1,参数2,参数3...)
fn.apply(借用者3,[参数1,参数2,参数3...])
12.正则表达式
验证和判断字符串
创建
var reg = /表达式内容/修饰符
var reg = new RegExp('表达式内容','修饰符')
验证
正则表达式.test('字符串')
返回true、false
由普通字符和特殊字符(元字符)构成
普通字符:字母、数字、_
特殊字符:
定位符
^a:以某个字符开头
a$:以某个字符结尾
^a$:a。同时使用^$,无论是内容还是字符个数都要匹配。整个字符串验证都要加
数量的限定符
a*:a个数为0到无穷多个
a+:a个数为1到无穷多个
a?:a个数为0到1个
a{n}:个数只能是n个,a{3}
a{n,m}:个数为[n,m]个,a{1,5}
a{n,}:个数为n到无穷个,a{3,}为大于等于3个
转义字符
\d:所有数字
\D:所有非数字
\w:字母、数字、下划线
\W:字母、数字、下划线之外的内容
\s:空白符(空格、制表符等)
\S:非空白符
备选字符集
[值1值2值3值4]:字符串要匹配到中括号里的任意一个值
[值1-值n]:值1到值n间的任意一个值,/^[a-zA-Z]$/任意的一个大小写
[^值1值2值3值4]:字符串不可以包括中括号里的任意一个值
[\u4e00-\u9fa5]:任意的一个汉字
修饰符
i:忽略大小写
g:全局匹配
ig/gi:既忽略大小写,也全局匹配
其他
abc\b:单词边界,匹配单词以abc结尾
abc\B:单词非边界,匹配单词以abc结尾或中间abc
.:点表示除\n之外的任意字符
exec方法,返回和正则匹配的字符串,类似match,一次匹配一个
/a/.exec('abcabc')
split、match、replace、search常和正则搭配
str.split(/\d/) 将字符串转化为数组,以数字为分隔符
'abcabc'.match(/a/g) --> ['a', 'a']
'abc12abc12abABC'.replace(/abc\b/ig,'*ok*') --> 'abc12abc12ab*ok*'
'12abc 12ab ABC'.replace(/abc\b/ig,'*ok*') --> '12*ok* 12ab *ok*'
'abc12abc12abABC'.replace(/abc\B/ig,'*ok*') --> '*ok*12*ok*12abABC'
贪婪模式、懒惰模式
如果正则中有表示数量的特殊符号(*、+、?、{n,m}等),在匹配时会尽可能多的匹配字符,默认
/a.+/
如果正则中有表示数量的特殊符号(*、+、?、{n,m}等),在匹配时会尽可能少的匹配字符
/a.+?/ 贪婪模式改为懒惰模式:在数量词后加?
13. 排序和查找
选择排序法 -- 拿一个数一行行比较,将最大放在最右侧
冒泡排序法 -- 两个相邻的比较,将最大的冒泡到最右侧
快速排序法 -- 选择一个元素作基准,两边排列
二分查找法 -- 一半半查找,数组必须是有序的
14.JSON
一种数据格式,本质是字符串,JavaScript Object Notation
window.JSON
构成元素:简单值(数值型、字符型、布尔型、null)、对象(存储无序属性)、数组(存储有序数据)
对象的键必须用双引号包起来
字符串必须用双引号包起来
'{"name":"Tom", "age":10}'
转化方法
JSON.parse() JSON 字符串 --> JS 数据类型
JSON.stringify() JS 数据类型 --> JSON 字符串
15.对象、原型、继承、原型链
- 面向过程、面向对象
- 在完成某个需求之前,先分析完成该需求所需要经历步骤有哪些,然后按照步骤一次执行。面向过程重在过程,C语言
- 在完成某个需求之前,先分析完成该需求所涉及的对象有哪些,然后在分析每个对象身上有哪些属性和方法,利用这些属性和方法完成相应的需求。Java、C++ JS是一门基于对象的语言
15.1 对象:具有特定功能的无序的属性和方法的集合
- 创建:字面量形式、构建方法
- 自定义构建方法和调用
- 构建方法在执行时流程
-
- 将实参传给形参,并创建个空对象,让this指向这个空对象
-
- 为空对象(this)绑定属性并初始化
-
- 将创建好的对象返回给外部
-
- 私有属性和公有属性
- 属性值每个独一份(不同)的放构建方法(私有属性)里,属性值相同的放“公共空间”(原型--公有属性),以减少内存资源浪费
- 静态属性和静态方法
- 给构造方法直接绑定的属性和方法
- 构建方法在执行时流程
- 自定义构建方法和调用
15.2 原型
- 每个函数都会有prototype属性,这个属性指向一个对象,这个对象称为原型
- 存储通过构建方法创建出来的所有对象可以共享的内容
- 构建方法名称.prototype --> 获取原型对象
- 对象可直接获得原型中的内容,每个对象都有__proto__属性,这个属性指向创建给对象时的原型对象。属性的查找顺序:自身私有属性 -> proto -> 原型对象属性
15.3 继承
- 在两个构建方法间建立起来的某种关系
- 继承方式有:
-
- 构建方法继承:继承的是上级构造方法对私有属性的绑定和初始化功能
function 构造方法1(){} function 构造方法2(){ 构造方法1.call/apply(this,...) } -
- 原型链继承:继承的是上级构造方法的私有属性,让下级的构建方法的prototype属性指向上级构建方法创建出来的一个实例(对象),还需要将prototype.constructor重新指回自己的构建方法
function 构造方法1(){} function 构造方法2(){} 构造方法2.prototype = new 构造方法1() 采用原型链继承,会导致下级构建方法原型中的constructor属性指向的改变(这个属性默认指向它的构建方法),需要将它重新指回自己的构建方法 -
- 组合继承,构建方法继承+组合继承
-
15.3 原型链:
通过原型链继承,在原型间建立的一条链式结构 对象属性的查找顺序:自身私有属性 -> proto -> 原型对象属性,如果也没有,沿着原型链继续向上查找,直至到Object的原型,如无返回undefined
16.this
- 函数运行时,自动生成的一个用来指代函数调用者的对象,只能在函数内部使用
- 函数调用者是谁,this就是谁
- this在正常函数中指向调用者
- 自执行函数,this指向window
- this在闭包中指向window
- 间接调用和延迟调用,this指向window
- call、apply函数,this指向第一个参数
- this在正常函数中指向调用者
17.instanceof
- 判断某个引用类型数据的具体类型
- 数据 instanceof 类型
18.hasOwnProperty、in、for in
- obj.hasOwnProperty('属性名称') 判断是否为对象的私有属性
- '属性名称' in obj 判断是否为对象的属性(私有和公有)
- for in 循环:遍历对象属性(私有和公有)
19.作用域链
- 每个函数都有的[[Scope]]属性,该属性指向一个集合,这个集合保存了当前作用域下面的变量对象的地址,以及上级作用域下面的变量对象地址,以及上上级直至全局作用域(window对象)
- 在使用某个变量时,先从当前作用域查找,若无,则沿着作用域链向上级作用域查找,直至找到window对象,若无则报错
20.闭包
- 广义:被定义在其他函数内部的函数就是一个闭包
- 狭义:外部函数返回的持有外部函数变量的内部函数
- 作用:可以将外部函数中定义的变量拿到函数外部来操作,即闭包在它所在的外部函数和全局环境间建立了桥梁
- 工作原理:函数在执行完毕后会从内存中弹出,其的作用链和变量对象会被销毁(没有再被引用就销毁)。而闭包函数的作用域链中包含了外部函数变量对象地址(仍被引用),因此保留了外部函数作用域
- 不足:由于闭包会将上级作用域下面的变量对象保存在内存中,那么如果有大量的闭包,会造成内存资源浪费,建议不使用时手动删除
21.设计模式--工厂模式
批量创建JS对象,本质是JS中的函数
function(a,b,...){
var obj = {}
obj.a = a
obj.b = b
obj.fn = function(){}
...
return obj
}