引用数据类型
RegExp(正则)
正则表达式的pattern可以是任何简单或者复杂的正则表达式
,每个正则表达式可以带0个或者多个flags
,用于控制表达式的行为。
正则表达式的创建
//字面创建
let expression = /pattern/flags
//例如:
let ex1 = /at/g //匹配所有的at
let ex2 = /[bc]at/i //匹配第一个bat或者cat,忽略大小写
let ex2-1 = /\[bc\]at/i //匹配第一个的[bc]at
let ex3 = /.at/gi //匹配所有以“at”结尾的三字符组合,忽略大小写,此处的“.”代表at前面的任意字符都可以匹配
let ex3-1 = /\.at/gi //匹配所有.at,忽略大小写,要匹配".at"需要对"."进行转义
//RegExp构造函数创建,接收两个参数,模式字符串和标记字符串(可选)
let Regexpression = new RegExp("at","g");
由于RegExp构造函数的两个参数都是字符串,所以在某些情况下需要二次转义,所有元字符都需要二次转义
例如
/\[bc\]at/ --> "\\[bc\\]at"
/\.at/ --> "\\.at"
RegExp可以基于已有的正则表达式实例,可选择性的修改他们的标记,创建有一个对象
let ex2-3 = new RegExp(ex2,"g");
表示匹配模式的标记flags
- g:`全局模式`,表示查找字符串中的所有匹配的内容,而不是只找到第一个就结束
- i:`不区分大小写`,匹配时忽略pattern和字符串的大小写
- m:`多行模式`,表示查找到一行文本末尾时会继续查找
- y:`粘附模式`,表示只查找从lastindex开始以及之后的字符串
- u:`Unicode模式`,启用Unicode匹配
- s:`dotAll模式`,表示元字符,表示匹配任何字符
所有元字符
必须要转义
元字符在正则表达式中有一种或者多种特殊功能,所以要匹配这些字符,需要用反斜杠\来转义如下所示
( [ { \ ^ $ | } ] ) ? * + .
[]
用来定义一个字符
或者几种字符
或者一个字符集合,[bB]
表示b或者B都可以匹配,[0-9]
表示0-9任何一个数字都可匹配,[A-Z]
表示任何一个大写字母A-Z都可以匹配"."
表示可以匹配除了换行符任何一个字符"^"
放在方括号里表示取非,如[^0-9]
表示不是0-9
的字符都可以匹配,单独
使用表示以...开头
"$"
表示结尾,^\d{5,12}$
表示5-12
位数字\d
表示匹配任意一个数字字符
,\D
表示匹配任意一个非数字字符
,\w
表示匹配任意一个字母、数字或下划线
,\W
表示匹配任意一个非字母、数字或下划线
\s
匹配一个空白字符,包括tab和换行,\S
表示匹配一个非空白字符- 在字符集后面加上
"+"
表示匹配的字符至少出现一次
;"*"
表示匹配字符出现零次或者多次
;"?"
表示匹配字符出现0次
或者1次
- 在字符或字符集或子表达式加
"{}"
可设定重复匹配次数
,如{2}
匹配两次、{2,4}
表示匹配2-4次,{2,}
表示匹配至少两次 |
表示或,2|3
表示2或3匹配\b
表示匹配是否到达单词边界,\B
表示匹配没有到达单词边界
示例:
[a-z]
匹配任何包含a-z的字符串
[A-Z]
[0-9]
等同于\d
[abc]
、
[^abc]
匹配不包含
小写字母abc的字符串
[a-zA-Z0-9_]
匹配数字、字母或者下划线,等同于\w
RegExp的实例属性
每个RegExp实例都有下列属性,提供有关模式
的相关信息
- global:是否设置了g
- ignoreCase:是否设置了i
- unicode,是否设置了u
- sticky,是否设置了y
- lastIndex,表示在源字符串中下一次搜索开始的位置
- multiline,是否设置了m标志
- dotAll,是否设置了s
- source,正则表达式的紫米阿娘字符串,没有开头和结尾的斜杠
- flags,正则表达式的标记字符串,
无论是字面创建
还是RegExp创建
,相同的正则表达式的source和flags相同
RegExp的实例方法
exec()
,配合捕获组
使用,接收一个参数,即要应用模式的字符串
,如果找到了匹配项,返回包含第一个匹配信息的数组,没找到则返回null,返回的数组是Array的实例,但包含两个额外的属性,index和input
,index是字符串中匹配模式的起始位置,input是要查找的字符串
。数组的第一个元素是匹配整个模式的字符串
,其他元素是与表达式中的捕获组
(用括号括起来的)匹配的字符串,没有捕获组则数组只包含一个元素test()
接收一个字符串参数,如果与模式匹配则返回true,否则false
let text = "000-00-0000";
let expression = /\d{3}-\d{2}-\d{4}/
if(expression.test(text)){
console.log(true);
}
toString()、toLocaleString()
返回正则表达式的字面量形式
valueOf()
方法返回正则表达式
本身
RegExp的构造函数属性
(像静态属性)
Date
Date常用方法
let date = new Date();
//常用的格式化日期的方法
//格式特定于实现
toDateString()显示日期中的周几、月、日、年
toTimeString()显示日期中的时、分、秒和时区
toUTCString()完整的UTC日期
//格式特定于实现和地区
toLocaleDateString()
toLocaleTimeString()
getTime()返回日期的毫秒表示
getFullYear()返回四位数年2019
getMonth()返回日期的月0-11
getDate()返回日期的日1-31
getDay()返回周几0-6
getHours()返回时0-23
getMinutes()返回日期中的分0-59
getSeconds()0-59
set
ES6提供了新的数据结构Set
。它类似于数组,但是成员的值都是唯一的
,没有重复
的值。 Set结构不会添加重复
的值。
const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
console.log(i);
}
// 去除数组重复成员的方法。
[...new Set(array)]
// 去除字符串里面的重复字符
[...new Set('ababbc')].join('')
// "abc"
基本方法和属性
- add(“xxx”)
- has(“xxx”)
- delete(“xxx”)
- size属性
Map
ES6提供了Map数据结构
。它类似于对象,也是键值对
的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键
。也就是说,Object 结构提供了“字符串—值”
的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。
Map创建
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
基本方法与属性
- set(“xxx”,“xxxx”),添加键值对
- get(“xxx”)、has(“xxxx”)可以用来查询,has返回true或者false,get返回值
- delete(“xxx”)和clear()可以用来删除,clear删除实例中的所有键,delete删除某个键值对
- size属性获取键值对数量
与Object的不同之处
- Map实例会维护键值对的插入顺序,因此可以根据插入顺序执行迭代操作。映射实例有一个迭代器能以插入顺序生成[key,value]形式的数组,可以通过entries()方法获得这个迭代器。
- 两者该如何选择?
- 内存占用,存储单个键值对所占用的内存数量会随键的数量线性增加,Map大约可以比Object多存储50%键值对
- 插入性能,涉及大量插入操作,Map性能更佳
- 查找速度,大量查找,Object更佳
- 删除性能,大量删除选择Map
引用类型要点
- 引用类型的值是可变的
var obj = {name:"zyj"};
obj.name = "percy";
obj.age = 21;
obj.giveMeAll = function(){
return this.name+":"+this.age;
};
obj.giveAll();
- 引用类型的比较是
引用
的比较
var obj1 = {}
var obj2 = {}
console.log(obj1 == obj2);//false
console.log(obj1 === obj2);//false
//obj1和obj2分别引用的是存放在堆内存中的两个不同的对象,所以变量的值也是不一样的
- 引用类型的
值
是保存在堆内存中的对象
- 栈内存中保存了
变量标识符和指向堆内存中该对象的指针
- 堆内存中保存了
对象的内容
-
函数其实是Function类型的实例,即函数也是对象,能够具有增强自身行为的方法
-
包装类型的存在使得原始值拥有类似对象的行为,Boolean、Number、String。每个包装类型都映射到对应的原始类型,当以读模式访问原始值时,后台会实例化一个原始值包装对象,通过这个对象可以操作数据,设计原始值的语句只要执行完就销毁
-
ES6新增Map、WeakMap、Set、WeakSet
-
JS内置对象Global和Math
js数据结构及数据存储
- 栈内存主要用于存储各种
基本类型的变量
,包括Boolean,Number,String,Undefined,Null,Symbol以及对象变量的指针
(A a = new A(),a就存在栈里) - 堆内存主要存储
object
(例如new出来的对象存在堆里) - 栈内存中的变量一般都是
已知大小
或者有范围上限
的,算作一种简单存储,按值访问,空间小,运行效率高 - 而
堆内存存储
的对象类型数据对于大小
来说,一般都是未知
的,由代码进行指定分配,空间大,无序存储
typeof和instanceof
typeof
可以用typeof()查看数据类型,经常用来检测一个变量是不是最基本的数据类型
console.log( typeof 123 ); // 'number'
console.log( typeof 'abc' ); // 'string'
console.log( typeof true); // 'boolean'
console.log( typeof function text(){ } ); // 'function'
console.log( typeof null); // 'object'
console.log( typeof undefined); // 'undefined'
var a;
typeof a; // undefined
a = null;
typeof a; // object
a = true;
typeof a; // boolean
a = 666;
typeof a; // number
a = "hello";
typeof a; // string
a = Symbol();
typeof a; // symbol
a = function(){}
typeof a; // function
a = [];
typeof a; // object
a = {};
typeof a; // object
a = /aaa/g;
typeof a; // object
类型 | typeof结果 |
---|---|
undefined | undefined |
null | object |
布尔值 | boolean |
数值 | number |
字符串 | string |
Symbol | symbol |
宿主对象,比如浏览器 | Implementation-dependent |
函数 | function |
其他对象 | object |
console.log( typeof ['1','2','3'] ); // 'object'
console.log( typeof {name:'张三'} ); // 'object'
判断一个变量的类型常常会用 typeof 运算符没有问题,但在使用 typeof 运算符时采用引用类型存储值
会出现一个问题,无论引用的是什么类型的对象
,他都会返回 object
,这正是 typeof 的局限性。
这就需要用到 instanceof
来检测某个对象是不是另一个对象的实例。
instanceof
- instanceof运算符可以用来判断
某个构造函数的prototype属性是否存在于另外一个要检测对象的原型链上
。简单说就是判断一个引用类型的变量具体是不是某种类型的对象 - 语法:object instanceof constructor
- 参数:object(要检测的对象)contructor(某个构造函数)
- 描述:instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上
- 注意:Object.creat(null)创造出来的是一个非Object实例的对象,instanceof检测出来的为false
function Foo() {}
function Bar() {}
Bar.prototype = new Foo();
new Bar() instanceof Bar; // true
new Bar() instanceof Foo; // true
// 如果仅仅设置 Bar.prototype 为函数 Foo 本身,而不是 Foo 构造函数的一个实例
Bar.prototype = Foo;
new Bar() instanceof Foo; // false
new String('foo') instanceof String; // true
new String('foo') instanceof Object; // true
'foo' instanceof String; // false
'foo' instanceof Object; // false
其他判断数据类型的方法(待完善)
Object.protptype.toString.call()
console.log(Object.prototype.toString(new RegExp('at')));//[object Object]
console.log(Object.prototype.toString.call(new RegExp('at')));//[object RegExp]
console.log(Object.prototype.toString.call([]));//object Array
console.log(Object.prototype.toString.call(testfunction));//object Function
console.log(Object.prototype.toString.call(new Date()));//object Date
console.log(Object.prototype.toString.call(111));//object Number
console.log(Object.prototype.toString.call("222"));//object String
console.log(Object.prototype.toString.call(true));//object Boolean
console.log(Object.prototype.toString.call(Symbol()));//object Symbol
let ex = new RegExp('at')
console.log(ex instanceof RegExp);// true
console.log(ex.toString());// /at/
Array.isArray
- typeof
- instanceof
- x.constructor.toString().indexOf(“Array”) > -1
总结
typeof
判断所有变量的类型,返回值有number,boolean,string,function,object,undefined。- typeof对于丰富的对象实例,只能返回"Object"字符串。
instanceof
用来判断对象,代码形式为obj1 instanceof obj2(obj1是否是obj2的实例),obj2必须为对象, 否则会报错!其返回值为布尔值。- instanceof可以对不同的对象实例进行判断,判断方法是根据对象的
原型链
依次向下查询,如果obj2的原型属性存在obj1的原型链上,(obj1 instanceof obj2)值为true。