JavaScript学习笔记--变量与数据类型(四)----引用数据类型RegExp、Date、Set、Map介绍,引用类型的存储以及数据类型判断

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"

基本方法和属性

  1. add(“xxx”)
  2. has(“xxx”)
  3. delete(“xxx”)
  4. 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"

基本方法与属性

  1. set(“xxx”,“xxxx”),添加键值对
  2. get(“xxx”)、has(“xxxx”)可以用来查询,has返回true或者false,get返回值
  3. delete(“xxx”)和clear()可以用来删除,clear删除实例中的所有键,delete删除某个键值对
  4. size属性获取键值对数量

与Object的不同之处

  • Map实例会维护键值对的插入顺序,因此可以根据插入顺序执行迭代操作。映射实例有一个迭代器能以插入顺序生成[key,value]形式的数组,可以通过entries()方法获得这个迭代器。
  • 两者该如何选择?
    1. 内存占用,存储单个键值对所占用的内存数量会随键的数量线性增加,Map大约可以比Object多存储50%键值对
    2. 插入性能,涉及大量插入操作,Map性能更佳
    3. 查找速度,大量查找,Object更佳
    4. 删除性能,大量删除选择Map

引用类型要点

  1. 引用类型的值是可变的
var obj = {name:"zyj"};
obj.name = "percy";
obj.age = 21;
obj.giveMeAll = function(){
    return this.name+":"+this.age;
};
obj.giveAll();
  1. 引用类型的比较是引用的比较
var obj1 = {}
var obj2 = {}

console.log(obj1 == obj2);//false
console.log(obj1 === obj2);//false
//obj1和obj2分别引用的是存放在堆内存中的两个不同的对象,所以变量的值也是不一样的
  1. 引用类型的是保存在堆内存中的对象
  • 栈内存中保存了变量标识符和指向堆内存中该对象的指针
  • 堆内存中保存了对象的内容
  1. 函数其实是Function类型的实例,即函数也是对象,能够具有增强自身行为的方法

  2. 包装类型的存在使得原始值拥有类似对象的行为,Boolean、Number、String。每个包装类型都映射到对应的原始类型,当以读模式访问原始值时,后台会实例化一个原始值包装对象,通过这个对象可以操作数据,设计原始值的语句只要执行完就销毁

  3. ES6新增Map、WeakMap、Set、WeakSet

  4. 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结果
undefinedundefined
nullobject
布尔值boolean
数值number
字符串string
Symbolsymbol
宿主对象,比如浏览器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

其他判断数据类型的方法(待完善)

  1. 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/
  1. Array.isArray
  2. typeof
  3. instanceof
  4. x.constructor.toString().indexOf(“Array”) > -1

总结

  1. typeof判断所有变量的类型,返回值有number,boolean,string,function,object,undefined。
  2. typeof对于丰富的对象实例,只能返回"Object"字符串。
  3. instanceof用来判断对象,代码形式为obj1 instanceof obj2(obj1是否是obj2的实例),obj2必须为对象, 否则会报错!其返回值为布尔值。
  4. instanceof可以对不同的对象实例进行判断,判断方法是根据对象的原型链依次向下查询,如果obj2的原型属性存在obj1的原型链上,(obj1 instanceof obj2)值为true。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值