前端:vue写界面、请求数据 数据处理
后端:写Api接口,接收用户数据,处理数据(数据库),返回数据
第一篇和第二篇主要讲原生js语言基本特性、es6和jquery,第三篇讲Node后端开发,第四篇讲框架
js基本语法
基本变量类型
js中有六种基本的数据类型:
数值number:整数和小数(比如1
和3.14
)
字符串string:文本(比如Hello World
)
布尔值boolean:表示真伪的两个特殊值,即true
(真)和false
(假)
undefined
:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值
null
:表示空值,即此处的值为空。
引用数据类型:
对象object:各种值组成的集合。
数组。对象和数组都是引用数据类型。
函数也是变量类型,属于对象的一种
判断变量类型
JavaScript有三种方法确定值的类型:typeof运算符、instanceof运算符、Object.toString方法。
typeof可以判断基本类型变量,返回类型的小写字母,如number、string、boolean、function、undefined、symbol等
instanceof运算符返回一个布尔值,表示对象是否为构造函数的实例,左边是实例,右边是原型,可以用来判断数组和对象,但不适用基本类型的值
对于数组,有时候会返回Object,因此ES5 提供了 Array.isArray() 方法 。该方法用以确认某个对象本身是否为 Array 类型,而不区分该对象在哪个环境中创建。
Object.prototype.toString()方法返回对象的类型字符串。
由于实例对象可能会自定义toString方法,覆盖掉Object.prototype.toString方法,所以为了得到类型字符串,通过call方法在 任意值上调用这个方法,判断这个值的类型
根据不同的数据类型返回值:
数值:返回[object Number]
字符串:返回[object String]
布尔值:返回[object Boolean]
Undefined: 返回[object Undefined]
Null:返回[object Null]
数组:返回[object Array]
函数:返回[object Function]
Date对象:返回[object Date]
利用这个特性可以写出比typeof更准确的类型判断函数
instanceof原理:检查右边构造函数的prototype属性,是否在左边对象的原型链上。只有一种特殊情况无法判断,就是左边对象的原型链上只有null对象,此时instance会失真。
1 | var obj = Object.create(null); |
数据类型转换
数据类型转换氛围强制转换和自动转换
parseInt()
方法用于将字符串转为整数,如果参数不是字符串,则先转为字符串再进行转换
转换的过程中是一个个字符依次转换,如果遇到不能转为数字的字符,就不能进行下去,返回已经转好的部分,如果字符串第一个字符就不能转化为数字,则返回NaN
parseInt()
方法接受第二个参数,表示被解析的值的进制,返回该值对应的十进制数,默认情况下第二个参数为10,第二个参数为0时默认也是10.
1 | parseInt('123') //123 |
parseFloat
方法用于将一个字符串转为浮点数,其他与parseInt相同
isNaN方法用来判断一个值是否为NaN
isFinite方法返回一个布尔值,判断一个值是否是正常的数值
经典面试题
[1,2,3].map(parseInt)
的返回结果:[1,NaN,NaN]
这种写法是以元素1,2,3作为元素,0,1,2作为下标分别求出parseInt(1,0),parseInt(2,1),parseInt(3,2)的值
第一个的值为1,第二个函数的第二个参数的范围为2-36,所以为NaN,第三个函数为二进制,但是数字为3,所以也为NaN;
强制类型转换主要用到Number、String、Boolean三个函数。
Number函数用于强制转换为数值
1 | //字符串转数字,可以被解析为数值的情况 |
String函数用于强制转换成字符串
1 | //转换基本类型 |
Boolean函数用于强制转换成布尔值。除了特定五个值的转换结果是false,其他全是true
1 | Boolean(undefined) //false |
自动转换
在某些特定的代码语句中会自动调用上述三个函数,起到自动转换的作用。
自动转换为布尔值
在条件语句中,用于将表达式转为布尔值
1 | //写法一 |
自动转换为字符串
在预期为字符串的地方会将非字符串的值转为字符串,有些坑
1 | '5'+1 //"51" |
自动转换为数值
在预期为数值的地方会将非字符串的值转为字符串,如运算符,
1 | '5' - '2' //3 |
运算符
一元操作符
delete 操作符
delete
操作符用于删除对象的某个属性或者一个数组中某一个键值;如果没有指向这个属性的引用,那它最终会被释放。
能使用 delete
删除各种各样的隐式声明, 但是被var
声明的除外。
如果 delete
操作成功,属性或者元素会变成 undefined
。如果 delete
可行会返回true
,如果不成功返回false
。
删除数组中的元素时,数组的长度是不变的,例如删除a[3]
, a[4]
,a[4]``和a[3]
仍然存在变成了undefined
。
1 | var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); |
关系操作符
in操作符
如果所指定的属性确实存在于所指定的对象中,则会返回true
1 | var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); |
三元运算符
三元条件运算符由问号(?)和冒号(:)组成,分隔三个表达式。如果问号前的表达式是true则返回第二个表达式的值,问号前的表达式为false时返回第三个表达式的值。
比较运算符
== 相等 ===严格相等 严格相等符要求两个值相等且为同一种类型时才返回true,如果值相等类型不同也返回false。相等会把数据转换成相同类型再进行比较。
NaN与任何值不相等,包括它自己。undefined和
null只有与自身比较,或者互相比较时,才会返回
true;与其他类型的值比较时,结果都为
false
1 | [1] == [1] //false |
void
void
运算符 对给定的表达式进行求值,然后返回 undefined
void 运算符通常只用于获取 undefined
的原始值,一般使用void(0)
(等同于void 0
)
字典
js中定义字典
1 | var dic = new Array()//通过申明一个Array来做一个字典 |
设置、修改值
1 | dic["q"] = "q1";//设置和修改值都可以使用该方法进行设定 |
遍历
1 | for (var key in dic) { |
删除值
1 | //两种方式 |
对象
javascript中的对象分为原生对象、内置对象和宿主对象三种。
原生对象:ECMAScript实现提供的对象,与宿主无关,在大部分js程序中都有。在运行过程中动态创建的对象,需要new
内置对象:属于原生对象的子集,在开发过程中不需要明确实例化,因为已经被实例化了。
宿主对象:由 ECMAScript 实现的宿主环境提供的对象,由宿主框架通过某种机制注册到ECscript引擎中的对象,宿主指js运行的环境,操作系统和浏览器。常见的宿主对象有window、location、history、screen、navigator、document.
内置对象
原生对象有17种,Object、function、Array、String、Boolean、Number、Date、RegExp、 Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError、Math 、Global.最后两种是内置对象,不可实例化。
js中内置17个对象,常用的是array对象,date对象、正则表达式对象、string对象、global对象
math对象
math.ceil():向上取整。 Math.sqrt(): 开平方
math.floor():向下取整。 Math.max():取最大值
math.round():四舍五入。 Math.min():取最小值
math.random():取0-1之间的随机数。 Math.abs():取绝对值
math.pow(x,y):
date对象
new Date(): 创建date对象。 get/setDate():返回或设置日期
Get/setFullYear():返回或设置年份,用四位数表示。 get/setmonth():获取/设置月份
get/setHours():返回小时,为24小时制。 get/setMinutes():返回分钟数
Get/setSeconds():返回/设置秒数。Get/setMilliSeconds():返回/设置秒数。
日期的获取
1 | new Date().getYear();//获取当前年份 |
Global对象
Global对象是一个固有对象,直接使用
正则表达式对象RegExp
正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用来按照“给定模式”匹配文本。比如,正则表达式给出一个 Email 地址的模式,然后用它来确定一个字符串是否为有效 Email 地址。
错误对象及处理机制
Javascript内部提供error对象进行错误处理机制。原始的Error
对象,以及6种衍生错误都是构造函数,可以手动生成错误对象的实例。这些构造函数都接受一个参数,代表错误提示信息
调用Error构造函数生成实例对象error。error实例对象必须有message
属性,表示出错时的提示信息,对Error
实例还提供name
和stack
属性,分别表示错误的名称和错误的堆栈。
1 | var err = new Error('出错了') |
Error实例对象是最一般的错误类型,在它的基础上JavaScript还定义了其他6种错误对象。也就是Error的6个派生对象。
SyntaxError
对象是解析代码时发生的语法错误。
ReferenceError
对象是引用一个不存在的变量时发生的错误。
RangeError
对象是一个值超出有效范围时发生的错误。主要有几种情况,一是数组长度为负数,二是Number
对象的方法参数超出范围,以及函数堆栈超过最大值。
TypeError
对象是变量或参数不是预期类型时发生的错误。比如,对字符串、布尔值、数值等原始类型的值使用new
命令,就会抛出这种错误,因为new
命令的参数应该是一个构造函数。
URIError
对象是 URI 相关函数的参数不正确时抛出的错误,主要涉及encodeURI()
、decodeURI()
、 encodeURIComponent()
、 decodeURIComponent()
、 escape()
和unescape()
这六个函数。
EvalError
对象是eval
函数没有被正确执行时,会抛出EvalError
错误。该错误类型已经不再使用了,只是为了保证与以前代码兼容,才继续保留。
除了以上错误类型,JavaScript允许用户自定义错误类型
1 | function UserError(message){ |
throw语句:
作用是手动停止程序,抛出一个错误
1 | if (x <= 0){ |
在上面的代码中,如果x小于等于0,就会手动抛出一个错误,告诉用户x的值不正确,整个程序就会在这里中断执行。throw抛出的错误由自己定义,上面的代码抛出一个Error错误。
Try…catch…finally语句:
JavaScript还提供了try...catch
结构,允许对错误进行处理,选择是否往下执行。如果没有catch,出现错误的话会直接停止。如果你不确定某些代码是否会报错,就可以把它们放在try...catch
代码块之中,便于进一步对错误进行处理。
catch
代码块捕获错误之后,程序不会中断,会按照正常流程继续执行下去。
try...catch
结构允许在最后添加一个finally
代码块,表示不管是否出现错误,都必需在最后运行的语句。
1 | openFile(); |
Object对象
Object对象是一个基础对象类型,其他所有对象都从 Object 继承了基本的属性和方法
1 | var obj = new Object();//新建对象 |
属性
Object.keys
方法的参数是一个对象,返回一个数组。该数组的成员都是该对象自身的(而不是继承的)所有属性名。
Object.getOwnPropertyNames
方法与Object.keys
类似,也是接受一个对象作为参数,返回一个数组,包含了该对象自身的所有属性名。
对于一般的对象来说,Object.keys()
和Object.getOwnPropertyNames()
返回的结果是一样的。只有涉及不可枚举属性时,才会有不一样的结果。Object.keys
方法只返回可枚举的属性
Object.getOwnPropertyDescriptor()
:获取某个属性的描述对象。
Object.defineProperty()
:通过描述对象,定义某个属性。
Object.defineProperties()
:通过描述对象,定义多个属性。
Object.create()
:该方法可以指定原型对象和属性,返回一个新的对象。
Object.getPrototypeOf()
:获取对象的Prototype
对象。
Object的实例对象方法
Object.prototype.valueOf()
:返回当前对象对应的值。默认情况下返回对象本身。
Object.prototype.toString()
:返回当前对象对应的字符串形式。
Object.prototype.toLocaleString()
:返回当前对象对应的本地字符串形式。
Object.prototype.hasOwnProperty()
:判断某个属性是否为当前对象自身的属性,还是继承自原型对象的属性。
Object.prototype.isPrototypeOf()
:判断当前对象是否为另一个对象的原型
Object.prototype.propertyIsEnumerable()
:判断某个属性是否可枚举。
方法
Object.setPrototypeOf
方法为参数对象设置原型,返回该参数对象。它接受两个参数,第一个是现有对象,第二个是原型对象。
Object.prototype.isPrototypeOf()
方法,用来判断该对象是否为参数对象的原型。
Object.prototype.__proto__
方法,实例对象的__proto__
属性(前后各两个下划线),返回该对象的原型。该属性可读写。
Object.getOwnPropertyNames
方法返回一个数组,成员是参数对象本身的所有属性的键名,不包含继承的属性键名。
Object.prototype.hasOwnProperty()
方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。
in
运算符返回一个布尔值,表示一个对象是否具有某个属性。它不区分该属性是对象自身的属性,还是继承的属性。
对象的拷贝
如果要拷贝一个对象,需要做到下面两件事情。
- 确保拷贝后的对象,与原对象具有同样的原型。
- 确保拷贝后的对象,与原对象具有同样的实例属性。
属性描述对象
JavaScript 提供了一个内部数据结构,用来描述对象的属性,控制它的行为,比如该属性是否可写、可遍历等等。这个内部数据结构称为“属性描述对象”(attributes object)。每个属性都有自己对应的属性描述对象,保存该属性的一些元信息。
属性描述对象提供6个元属性。
value:value
是该属性的属性值,默认为undefined
。
writable:writable
是一个布尔值,表示属性值(value)是否可改变(即是否可写),默认为true
。
enumerable:enumerable
是一个布尔值,表示该属性是否可遍历,默认为true
。
configurable: configurable
是一个布尔值,表示可配置性,默认为true
get: get
是一个函数,表示该属性的取值函数(getter)
Set: set
是一个函数,表示该属性的存值函数(setter)
get和set属于目标函数的存取器,一旦对目标属性定义了存取器,那么存取的时候,都将执行对应的函数。利用这个功能,可以实现许多高级特性,比如定制属性的读取和赋值行为。
取值函数get
不能接受参数,存值函数set
只能接受一个参数(即属性的值)。
存取器往往用于,属性的值依赖对象内部数据的场合。
1 | var obj ={ |
基于属性描述对象的方法控制对象的属性
Object.preventExtensions()
:防止对象扩展。
Object.isExtensible()
:判断对象是否可扩展。
Object.seal()
:禁止对象配置。
Object.isSealed()
:判断一个对象是否可配置。
Object.freeze()
:冻结一个对象。
Object.isFrozen()
:判断一个对象是否被冻结。
数组对象
实例属性
length:表示取得当前数组长度
实例方法
push() : 在数组末尾增加元素
pop() : 数组末尾删除
concat(ary2):数组拼接 concat不传参时为克隆数组
tostring():数组转成以逗号分隔的字符串
shift(): 移除数组中第一个元素
unshift():添加到数组第一个元素
slice(start,end):返回数组中的一段
splice(start, count, addElement1, addElement2):方法用于删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素。
sort():对数组进行排序
reverse():反转数组的排序
tolocalstring():返回当前
foreach:对数组中的每一项运行给定函数,没有返回值,只是根据原数组中的元素进行操作
1 | Array.foreach(function(value, index){ |
映射到函数map:对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
1 | arr1=arr.map(function(value,index){ |
过滤数组filter:给数组中的每一项运行给指定函数,返回满足过滤条件的组成新数组
1 | arr1=arr.filter(function(value,index){ |
判断每一项every:every()判断数组每一项是否满足条件,返回布尔值,全部满足返回true
1 | var res = arr.every(function (value,index){ |
判断有:数组中是否存在满足条件的项,只要有一项满足条件,就会返回true
1 | var res=arr.some(function (value,index){ |
包装对象
三种原始类型的值——数值、字符串、布尔值——在一定条件下,也会自动转为对象,也就是原始类型的“包装对象”。
即,包装对象是指的是与数值、字符串、布尔值分别相对应的Number
、String
、Boolean
三个原生对象。这三个原生对象可以把原始类型的值变成(包装成)对象。
String对象
方法
String.fromCharCode()
该方法的参数是一个或多个数值,代表 Unicode 码点,返回值是这些码点组成的字符串。
属性
String.length
返回字符串的长度
实例方法
String.charAt(1)
返回指定位置的字符
String.charCodeAt(1)
返回指定位置的Unicode码点
String.concat(String2)
连接两个字符串,返回一个新字符串,不改变原字符串。
String.slice(2,4)
从原字符串中取出指定字符串并返回,不改变原字符串。第一个参数的开始截取的位置,第二个参数是终止截取的位置
String.indexOf('string')
方法用于确定一个字符串在另一个字符串中第一次出现的位置,返回结果是匹配开始的位置。如果返回-1
,就表示不匹配。
String.lastIndexOf('string')
方法与indexOf方法类似,区别是从最后往前开始匹配
String.trim()
方法去掉字符串两端的空格、换行符、回车符、制表符等。
String.toLowerCase()/String.toUpperCase()
方法用于将一个字符串全部转为小写/大写
String.match('at')
方法用于确定原字符串是否匹配某个子字符串,返回一个数组,成员为匹配的第一个字符串。如果没有找到匹配,则返回null
。
String.search('at')
方法用于确定原字符串匹配某个子字符串的位置,返回整数。如果没有找到匹配,则返回-1
。
String.replace('a','b')
方法用第二个参数替换字符串中的第一个参数,一般情况下只替换第一个匹配。
String.split('|')
方法按照给定规则分割字符串,返回一个由分割出来的子字符串组成的数组。如果分割规则为空字符串,则返回数组的成员是原字符串的每一个字符。如果没有参数,则返回数组的唯一成员就是原字符串。如果即两个分割符中间没有其他字符,则返回数组之中会有一个空字符串。如果满足分割规则的部分处于字符串的开头或结尾(即它的前面或后面没有其他字符),则返回数组的第一个或最后一个成员是一个空字符串。
String.localeCompare('String1')
比较两个字符串,返回一个整数。如果小于0,表示第一个字符串小于第二个字符串;如果等于0,表示两者相等;如果大于0,表示第一个字符串大于第二个字符串。
Number对象
实例方法
(Number).toString
用来将一个数值转为字符串形式。
(Number).toFixed(2)
方法先将一个数转为指定位数的小数,然后返回这个小数对应的字符串。
(Number).toExponential(2)
方法将整数转化为科学记数法的字符串表示
(Number)toPrecision()
方法用于将一个数转为指定位数的有效数字。
Boolean对象
使用双重的否运算符(!
)也可以将任意值转为对应的布尔值。
1 | !!undefined // false |
RegExp正则表达式对象
https://juejin.im/post/6844904021325512717
https://juejin.im/post/6844904182835757064#heading-6
正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用来按照“给定模式”匹配文本。比如,正则表达式给出一个 Email 地址的模式,然后用它来确定一个字符串是否为 Email 地址。
新建正则表达式对象
1 | var regex = new RegExp('xyz', 'i'); |
正则表达式的实例属性
String.prototype.match()
:返回一个数组,成员是所有匹配的子字符串。
String.prototype.search()
:按照给定的正则表达式进行搜索,返回一个整数,表示匹配开始的位置。
String.prototype.replace()
:按照给定的正则表达式进行替换,返回替换后的字符串。
String.prototype.split()
:按照给定规则进行字符串分割,返回一个数组,包含分割后的各个成员。
正则匹配规则
js定义了很多字符匹配规则,大大方便了正则表达式的使用。
1.字面量字符与元字符
大部分字符在正则表达式中,就是字面的含义,比如/a/
匹配a
,/b/
匹配b
。在正则表达式之中,只表示它字面的含义的字符(就像前面的a
和b
)就叫做“字面量字符”
除了字面量字符以外,还有一部分字符有特殊含义,不代表字面的意思。它们叫做“元字符”(metacharacters),主要有以下几个。
元字符包括:
(1). :点字符(.
)匹配除回车(\r
)、换行(\n
) 、行分隔符(\u2028
)和段分隔符(\u2029
)以外的所有字符。注意,对于码点大于0xFFFF
字符,点字符不能正确匹配,会认为这是两个字符。通常把点字符用作占位符,表示匹配特定结构。
(2)位置字符:有一些符号限制匹配字符出现的位置,只有出现在指定的位置才算匹配正确。^
表示字符串的开始位置,$
表示字符串的结束位置
(3)选择字符:选择字符表示匹配几项中的一项就算匹配成功。
2.转义符
正则表达式中那些有特殊含义的元字符,如果要匹配它们本身,就需要在它们前面要加上反斜杠。比如要匹配+
,就要写成\+
。
正则表达式中,需要反斜杠转义的,一共有12个字符:^
、.
、[
、$
、(
、)
、|
、*
、+
、?
、{
和\
。
需要特别注意的是,如果使用RegExp
方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次。
3.字符类
字符类(class)表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内,比如[xyz]
表示x
、y
、z
之中任选一个匹配。
脱字符
如果方括号内的第一个字符是[^]
,则表示除了字符类之中的字符,其他字符都可以匹配。比如,[^xyz]
表示除了x
、y
、z
之外都可以匹配。
连字符
某些情况下,对于连续序列的字符,连字符(-
)用来提供简写形式,表示字符的连续范围。比如,[abc]
可以写成[a-c]
,[0123456789]
可以写成[0-9]
,同理[A-Z]
表示26个大写字母。
4.预定义模式
预定义模式是某些常见模式的简写。
\d
匹配0-9之间的任一数字,相当于[0-9]
。\D
匹配所有0-9以外的字符,相当于[^0-9]
。\w
匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
。\W
除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]
。\s
匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f]
。\S
匹配非空格的字符,相当于[^ \t\r\n\v\f]
。\b
匹配词的边界。\B
匹配非词边界,即在词的内部。
5.重复类
模式的精确匹配次数,使用大括号({}
)表示。{n}
表示恰好重复n
次,{n,}
表示至少重复n
次,{n,m}
表示重复不少于n
次,不多于m
次。
6.量词符
量词符是特殊的重复类,用来设定某个模式出现的次数。
?
问号表示某个模式出现0次或1次,等同于{0, 1}
。
*
星号表示某个模式出现0次或多次,等同于{0,}
。
+
加号表示某个模式出现1次或多次,等同于{1,}
。
7.贪婪模式与非贪婪模式
上一小节的三个量词符,默认情况下都是最大可能匹配,即匹配到下一个字符不满足匹配规则为止。这被称为贪婪模式。
除了贪婪模式,还有非贪婪模式,即最小可能匹配。只要一发现匹配,就返回结果,不要往下检查。如果想将贪婪模式改为非贪婪模式,可以在量词符后面加一个问号。
除了非贪婪模式的加号(+?
),还有非贪婪模式的星号(*?
)和非贪婪模式的问号(??
)。
+?
:表示某个模式出现1次或多次,匹配时采用非贪婪模式。*?
:表示某个模式出现0次或多次,匹配时采用非贪婪模式。??
:表格某个模式出现0次或1次,匹配时采用非贪婪模式。
8.正则修饰符
修饰符(modifier)表示模式的附加规则,放在正则模式的最尾部。
g修饰符。默认情况下,第一次匹配成功后,正则对象就停止向下匹配了。g
修饰符表示全局匹配(global),加上它以后,正则对象将匹配全部符合条件的结果,主要用于搜索和替换。
i修饰符。默认情况下,正则对象区分字母的大小写,加上i
修饰符以后表示忽略大小写
m修饰符。m
修饰符表示多行模式(multiline),会修改^
和$
的行为。默认情况下(即不加m
修饰符时),^
和$
匹配字符串的开始处和结尾处,加上m
修饰符以后,^
和$
还会匹配行首和行尾,即^
和$
会识别换行符(\n
)
9.组匹配
(?:x)
称为非捕获组(Non-capturing group),表示不返回该组匹配的内容,即匹配的结果中不计入这个括号。
注意,使用组匹配时,不宜同时使用g
修饰符,否则match
方法不会捕获分组的内容。
10.先行断言
x(?=y)
称为先行断言(Positive look-ahead),x
只有在y
前面才匹配,y
不会被计入返回结果。比如,要匹配后面跟着百分号的数字,可以写成/\d+(?=%)/
。
先行否定断言
x(?!y)
称为先行否定断言(Negative look-ahead),x
只有不在y
前面才匹配,y
不会被计入返回结果。比如,要匹配后面跟的不是百分号的数字,就要写成/\d+(?!%)/
。
常用的 JS正则表达式整理
1 | 1 数字:^[0-9]*$ |
校验字符的表达式
1 | 1 汉字:^[\u4e00-\u9fa5]{0,}$ |
其他常用正则表达式
1 | 1. 火车车次:/^[GCDZTSPKXLY1-9]\d{1,4}$/ |
Json对象
JSON 格式(JavaScript Object Notation 的缩写)是一种用于数据交换的文本格式,2001年由 Douglas Crockford 提出,目的是取代繁琐笨重的 XML 格式。
相比 XML 格式,JSON 格式有两个显著的优点:
书写简单,一目了然;
符合 JavaScript 原生语法,可以由解释引擎直接处理,不用另外添加解析代码。
所以,JSON 迅速被接受,已经成为各大网站交换数据的标准格式,并被写入标准。
JSON
对象是 JavaScript 的原生对象,用来处理 JSON 格式数据。
json格式的规定
1 | 1.复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。 |
Json对象的方法
JSON.stringify
方法用于将一个值转为 JSON 字符串。该字符串符合 JSON 格式,并且可以被JSON.parse
方法还原。
JSON.parse
方法用于将 JSON 字符串转换成对应的值。
JSON.stringify()的几种妙用:
判断数组是否包含某对象,或者判断对象是否相等。
1 | let data = [ |
判断两数组/对象是否相等
1 | let a = [1,2,3], |
让localStorage/sessionStorage可以存储对象。
localStorage/sessionStorage默认只能存储字符串,而实际开发中,我们往往需要存储的数据多为对象类型,那么这里我们就可以在存储时利用json.stringify()将对象转为字符串,而在取缓存时,只需配合json.parse()转回对象即可
1 | //存 |
eval函数
除了JSON.parse可以将字符串转换为json,还可以使用eval函数。eval函数可以执行任意的JavaScript代码
1 | var testJson = '{ "name": "小强", "age": 16 }'; |
也可以自己写一个function将字符串转为json
1 | var jsonStr = '{"userName": "tiu","userAge": 26,"isMale": true}'; |
Json方法的处理
json对象的特殊在于,如果传入的字符串不是有效的 JSON 格式,JSON.parse()
方法将报错
报错之后js就会停止运行,所以为了处理解析错误,可以将JSON.parse()
方法放在try...catch
代码块中
1 | try { |
好一点的处理是捕获报错之后返回一个默认值
1 | const jsonStringTransformer = <ValueType = any>( |
数组对象的研究
数组是无类型的,数组元素可以是任意类型,同一个数组中的元素也可能是不同类型
数组是动态的:可以根据需要增长或者缩短
数组可能是稀疏的: 数组元素的索引不一定是连续的
数组即使设置了初始长度,但是其超出长度之外的值依然可以显示,而且js中的数组再定义时可以不设长度
那么设置数组长度的意义是什么?
如果设置了数组长度,那么代码在执行时会在初始化的时候就给数据分配一个空间,以后每次给数组赋值就会更快。反之如果没有设置长度,代码在每次执行赋值时会先给数组增加长度,分配空间,降低运行速度。 d
各方法返回值汇总
返回数值:push()、unshift()、indexof()
返回字符串:join()
返回布尔值:includes()、every()、some()、findindex()
返回新数组:pop()、shift()、sort()、reverse()、concat()、slice()、fill()、map()、filter()、find()\ reduce()
没有返回值:foreach()
不改变原数组:slice()、include()、indexof()、findindex()、、、、
改变原数组:sort()、reverse()、splice()、fill()、map()、filter()、reduce()、push()、pop()、
数组常见操作
- 在指定位置删除或者添加元素:splice方法,改变原数组
1 | var a = ['a', 'b', 'c', 'd', 'e', 'f']; |
还可以使用delete方法,但是delete方法只能将原位置变为undefined,不能自动改变数组长度
1 | delete arr[index] |
- 从对象数组中提取对象的指定属性为数组
1 | objArray = [ { foo: 1, bar: 2}, { foo: 3, bar: 4}, { foo: 5, bar: 6} ]; |
数组sort方法
排序方法
sort方法默认是按照字典的顺序排的,也就是先转换成字符串,然后在进行从小到大排序,而不是直接按照大小进行排序
1 | ['d', 'c', 'b', 'a'].sort() |
如果想让sort
方法按照自定义方式排序,可以传入一个函数作为参数。该函数本身接受两个参数,表示进行比较的两个数组成员。如果该函数的返回值大于0
,表示第一个成员排在第二个成员后面;其他情况下,都是第一个元素排在第二个元素前面。
自定义的排序函数应该返回数值,否则不同的浏览器可能有不同的实现,不能保证结果都一致。
稳定性
reduce方法
对象中的某属性求和
1 | //值数组 |
将二维数组/多维数组转化为1维
1 | //将二维数组转化为一维 |
一维数组转为二维数组
1 | function oneTransTwo(source, num) { |
数组去重
1 | //数组去重 |
计算每个元素出现的次数
1 | //计算数组中每个元素出现的次数 |
按属性分类
1 | var people = [ |
按属性去重
1 | let array = array.reduce(function (item, next) { |
按顺序执行promise
1 | function runPromiseInSequence(arr, input) { |
功能型函数管道
1 | // Building-blocks to use for composition |