基本数据类型
- 分类(2大类)
- 基本(值)类型
- Number: 任意数值
- String: 任意文本
- Boolean: true/false
- undefined: undefined
- null: null
- 对象(引用)类型
- Object: 任意对象
- Array: 特别的对象类型(下标/内部数据有序)
- Function: 特别的对象类型(可执行)
- 判断
- typeof:
- 可以区别: 数值, 字符串, 布尔值, undefined, function
- 不能区别: null与对象, 一般对象与数组
- instanceof
- 专门用来判断对象数据的类型: Object, Array与Function
- ===
- 可以判断: undefined和null
let、const、var
Let:
- 在同一个块级作用域,变量不能重复声明
2.是块级作用域
3.不存在变量提升
4.不影响作用域链
Const:
1.一定要赋初始值(值不能修改的常量)
2.一般常量使用大写(潜规则)
3.常量的值不能修改
4.块级作用域
对数组和对象的元素修改,不算对常量的修改,不会报错,因为这个常量指向的地址没有改变
Var:
1.全局变量
2.有变量提升
3.影响了变量的作用域
函数外部:变量不管是否用了var申明,都是全局变量。
函数内部:变量如果没有使用var关键字申明,那它就是全局变量,只有用var关键字申明了,才是局部变量。
4.可以重复声明
str1 = 'Hello JavaScript!';
function fun1() {
var str1 = 'Hello Java!';
}
fun1();
alert(str1);
// 弹出 Hello JavaScript!
str1 的值并没有被函数 fun1 改变。
以下是一个经典的关于 var 和 let 的一个例子:
以下会输出10个10:因为这个在setTimeout函数外部声明了var i,此时函数内部的i就是外部的i,for循环执行速度很快完毕后var为10
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i);
}, 100);
}
{
var i = 0;
}
{
var i = 1;
}
{
var i = 2;
}
//此时最后的结果i=10了,所以会一直输出10
以下输出0-9:用let声明i,
for (let i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i);
}, 100);
}
{
let i = 0;
setTimeout(function () {
console.log(i); //该函数内部没有声明i,向函数外部查找
}, 100);
}
{
let i = 1;
}
{
let i = 2;
}
解构赋值
ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
- 数组的结构
const F4 = ['小沈阳','刘能','赵四','宋小宝'];
let [xiao, liu, zhao, song] = F4;
- 对象的解构
const zhao = {
name: '赵本山',
age: '不详',
xiaopin: function(){
console.log("我可以演小品");
}
};
let {name, age, xiaopin} = zhao;
模板字符串(反引号``)
//1. 声明
let str = `我也是一个字符串哦!`;
console.log(str, typeof str);
//2. 内容中可以直接出现换行符
let str = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`;
//3. 变量拼接
let lovest = '魏翔';
let out = `${lovest}是我心目中最搞笑的演员!!`;
console.log(out);
简化对象写法
类似语法糖
//ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。
//这样的书写更加简洁
let name = '尚硅谷';
let change = function(){
console.log('我们可以改变你!!');
}
const school = {
name,
change,
improve(){
console.log("我们可以提高你的技能");
}
}
箭头函数
1.箭头函数不能用new来创建构造函数的实例,普通函数可以(因为箭头函数创建的时候程序不会为它创建construct方法,也就是没有构造能力,用完就丢掉了,不像普通函数重复利用,因此也不需要构造函数原型,也就是不会自动生成prototype属性)
2.程序不会给箭头函数创建arguments对象
3.普通函数中的this是动态的,而箭头函数中的this指向的是紧紧包裹箭头函数的那个对象(定义时决定的)
4.箭头函数不能通过bind、call、apply来改变this的值,但依然可以调用这几个方法(只是this的值不受这几个方法控制)
箭头函数与普通函数的this指向
普通函数this指向:它作为某个对象的方法被调用时,那么这个this指向就是这个对象(其this指向可以通过call、apply、bind改变)
箭头函数this指向:其指向与定义这个函数的上下文有关,往它定义函数的外层去寻找,而不是谁调用this便为谁
this指向遇到闭包
闭包里面的this默认指向window
情况一:作用域链指向0
情况二:作用域链指向1
函数形参的默认值设置
ES6 允许给函数参数赋值初始值
- 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
function add(a,c=10,b) {
return a + b + c;
}
let result = add(1,2);
- 与解构赋值结合
function connect({host="127.0.0.1", username,password, port}){
console.log(host)
console.log(username)
console.log(password)
console.log(port)
}
connect({
host: 'atguigu.com',
username: 'root',
password: 'root',
port: 3306
})
rest参数
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
ES5 获取实参的方式(arguments),此处的arguments是一个对象,不是数组
function date(){
console.log(arguments);
}
date('a','b','c');
rest 参数,是一个数组,rest 参数必须要放到参数最后
function date(...args) {
console.log(args); // filter some every map
}
date("a", "b", "c");
function fn(a, b, ...args) {
console.log(a);//1
console.log(b);//2
console.log(args);//3456
}
fn(1, 2, 3, 4, 5, 6);
扩展运算符(…)
…扩展运算符能将数组转换为逗号分隔的参数序列
const arr=[1,2,3,4]
console.log(...arr);//1,2,3,4
应用:
一:数组的合并
const kuaizi = ['王太利','肖央'];
const fenghuang = ['曾毅','玲花'];
const merge = [...kuaizi, ...fenghuang];
console.log(merge);
二:数组的克隆
const sanzhihua = ["E", "G", "M"];
const sanyecao = [...sanzhihua]; // ['E','G','M']
console.log(sanyecao);
三:将伪数组转换为真正的数组
const divs = document.querySelectorAll("div");
const divArr = [...divs];
console.log(divArr); // arguments
symbol
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是
JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol 特点:
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol 值不能与其他数据进行运算
- Symbol 定义 的 对象属 性 不能 使 用 for…in 循 环遍 历 ,但 是可 以 使 用
Reflect.ownKeys 来获取对象的所有键名
//创建Symbol
let s = Symbol();
let s2 = Symbol("尚硅谷");
let s3 = Symbol("尚硅谷");
console.log(s2 === s3); //false
//Symbol.for 创建
let s4 = Symbol.for("尚硅谷");
let s5 = Symbol.for("尚硅谷");
console.log(s4 === s5); //true
//不能与其他数据进行运算,均会报错
let result = s + 100;
let result = s > 100;
let result = s + s;
给对象添加symbol属性的方式:
//向对象中添加方法 up down
let game = {
name: "俄罗斯方块",
up: function () {},
down: function () {},
};
//声明一个对象,两种添加方式
let methods = {
up: Symbol(),
down: Symbol(),
};
game[methods.up] = function () {
console.log("我可以改变形状");
};
game[methods.down] = function () {
console.log("我可以快速下降!!");
};
console.log(game);
let youxi = {
name: "狼人杀",
[Symbol("say")]: function () {
console.log("我可以发言");
},
[Symbol("zibao")]: function () {
console.log("我可以自爆");
},
};
console.log(youxi);
迭代器
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
- ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
- 原生具备 iterator 接口的数据(可用 for of 遍历)
a) Array
b) Arguments
c) Set
d) Map
e) String
f) TypedArray
g) NodeList - 工作原理
a) 创建一个指针对象,指向当前数据结构的起始位置
b) 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
c) 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
d) 每调用 next 方法返回一个包含 value 和 done 属性的对象
注: 需要自定义遍历数据的时候,要想到迭代器。
//声明一个数组
const xiyou = ["唐僧", "孙悟空", "猪八戒", "沙僧"];
//使用 for...of 遍历数组(键值),for in遍历是键名
// for(let v of xiyou){
// console.log(v);
// }
let iterator = xiyou[Symbol.iterator]();
//调用对象的next方法
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
自定义遍历数据:
//需求,使用for of遍历,每次返回stus中的值
//声明一个对象
const banji = {
name: "终极一班",
stus: [
"xiaoming", //第一次
"xiaoning", //第二次
"xiaotian", //第三次
"knight", //第四次
],
//定义一个迭代器实现自定义遍历数据
[Symbol.iterator]() {
//索引变量
let index = 0;
let _this = this;
return {
next: function () {
if (index < _this.stus.length) {
//这是一个闭包,this指向window,所以在外部令 let _this = this;,让_this指向banji
const result = { value: _this.stus[index], done: false };
//下标自增
index++;
//返回结果
return result;
} else {
return { value: undefined, done: true };
}
},
};
},
};
//遍历这个对象,如果没有定义迭代器,会报错
for (let v of banji) {
console.log(v);
}
生成器
专门针对异步编程的解决方案,可以解决回调地狱
//生成器其实就是一个特殊的函数
//类似异步编程 纯回调函数 node fs ajax mongodb
//yield函数代码的分隔符
function* gen() {
yield "一只没有耳朵";
yield "一只没有尾部";
yield "真奇怪";
}
let iterator = gen();
//通过调用next方法来向下执行代码,且yield后的内容是返回结果
console.log(iterator);//不输出任何内容
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
//遍历
for (let v of gen()) {
console.log(v);
}
生成器参数:
function* gen(arg) {
console.log(arg);
let one = yield 111;
console.log(one);
let two = yield 222;
console.log(two);
let three = yield 333;
console.log(three);
}
//执行获取迭代器对象
let iterator = gen("AAA");
console.log(iterator.next());
//next方法可以传入实参,参数作为上一个yield语句的返回结果
console.log(iterator.next("BBB"));
console.log(iterator.next("CCC"));
console.log(iterator.next("DDD"));
应用:
需求:1s 后控制台输出 111 2s后输出 222 3s后输出 333
// 异步编程 文件操作 网络操作(ajax, request) 数据库操作
// 回调地狱
// setTimeout(() => {
// console.log(111);
// setTimeout(() => {
// console.log(222);
// setTimeout(() => {
// console.log(333);
// }, 3000);
// }, 2000);
// }, 1000);
function one(){
setTimeout(()=>{
console.log(111);
iterator.next();
},1000)
}
function two(){
setTimeout(()=>{
console.log(222);
iterator.next();
},2000)
}
function three(){
setTimeout(()=>{
console.log(333);
iterator.next();
},3000)
}
function * gen(){
yield one();
yield two();
yield three();
}
//调用生成器函数
let iterator = gen();
iterator.next();
应用2:模拟获取 用户数据 订单数据 商品数据
function getUsers() {
setTimeout(() => {
let data = "用户数据";
//调用 next 方法, 并且将数据传入,作为yield getUsers()结果的返回
iterator.next(data);
}, 1000);
}
function getOrders(value) {
setTimeout(() => {
let data = "订单数据+" + value;
iterator.next(data);
}, 1000);
}
function getGoods(value) {
setTimeout(() => {
let data = "商品数据+" + value;
iterator.next(data);
}, 1000);
}
function* gen() {
let users = yield getUsers();
console.log("users", users); //输出用户数据
let orders = yield getOrders(users);
console.log("orders", orders); //输出订单数据+用户数据
let goods = yield getGoods(orders);
console.log("goods", goods); //输出商品数据+订单数据+用户数据
}
//调用生成器函数
let iterator = gen();
iterator.next();
promise
Promise 是 ES6 引入的异步编程的新解决方案。与生成器类似,可以解决回调地狱问题
语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
- Promise 构造函数: Promise (excutor) {}
- Promise.prototype.then 方法
- Promise.prototype.catch 方法
有三个状态,初始化、成功、失败
//实例化 Promise 对象
const p = new Promise(function (resolve, reject) {
setTimeout(function () {
//
// let data = '数据库中的用户数据';
// resolve
// resolve(data);
let err = "数据读取失败";
reject(err);
}, 1000);
});
//调用 promise 对象的 then 方法
p.then((res) => {
//上面调用resolve(data),输出数据库中的用户数据
console.log(res);
}).catch((err) => {
//上面调用reject(err),输出数据读取失败
console.log(err);
});
集合Set(可以自动去重)
一般结合扩展运算符使用
它类似于数组,但成员的值都是唯一的
集合的属性和方法:(与map类似)
- size 返回集合的元素个数
- add 增加一个新元素,返回当前集合
- delete 删除元素,返回 boolean 值
- has 检测集合中是否包含某个元素,返回 boolean 值
- clear 清空集合,返回 undefined
可以将数组变成集合并且去重,集合也可以重新变成数组
let s2 = new Set(["大事儿", "小事儿", "好事儿", "坏事儿", "小事儿"]);
例子:
let arr = [1,2,3,4,5,4,3,2,1];
//1. 数组去重
let result = [...new Set(arr)];
console.log(result);
//2. 交集
let arr2 = [4,5,6,5,6];
let add = result.filter(item => new Set(arr2).has(item));
console.log(add);
//3. 并集
let union = [...new Set([...arr, ...arr2])];
console.log(union);
//4. 差集,与交集相反
let diff = result.filter(item => !(new Set(arr2).has(item)));
console.log(diff);
Map
它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
Map 的属性和方法:
- size 返回 Map 的元素个数
- set 增加一个新元素,返回当前 Map
- get 返回键名对象的键值
- has 检测 Map 中是否包含某个元素,返回 boolean 值
- clear 清空集合,返回 undefined
//声明 Map
let m = new Map();
//添加元素
m.set("name", "尚硅谷");
m.set("change", function () {
console.log("我们可以改变你!!");
});
let key = {
school: "ATGUIGU",
};
m.set(key, ["北京", "上海", "深圳"]);
console.log(m);
//删除
m.delete('name');
//获取
console.log(m.get('change'));
console.log(m.get(key));
//清空
m.clear();
//遍历
for (let v of m) {
console.log(v);
}
对象方法扩展
- Object.is 判断两个值是否完全相等
- Object.assign 对象的合并,出现重名时后面的属性会覆盖前面的属性
- Object.setPrototypeOf 设置原型对象 Object.getPrototypeof
//1. Object.is 判断两个值是否完全相等
console.log(Object.is(120, 120)); // true
console.log(Object.is(NaN, NaN)); //true
console.log(NaN === NaN); // false
//2. Object.assign 对象的合并,出现重名时后面的属性会覆盖前面的属性
const config1 = {
host: "localhost",
port: 3306,
name: "root",
pass: "root",
test: "test",
};
const config2 = {
host: "http://atguigu.com",
port: 33060,
name: "atguigu.com",
pass: "iloveyou",
test2: "test2",
};
console.log(Object.assign(config1, config2));
//3. Object.setPrototypeOf 设置原型对象 Object.getPrototypeof
const school = {
name: "尚硅谷",
};
const cities = {
xiaoqu: ["北京", "上海", "深圳"],
};
Object.setPrototypeOf(school, cities);
console.log(Object.getPrototypeOf(school));
console.log(school);
ES7(includes)
includes:返回的是true、false
indexOf:es6方法,判断数组中是否存在某元素,不存在返回-1,存在返回该元素在数组中的下标
ES8(async、await)
async 和 await 两种语法结合可以让异步代码像同步代码一样
async函数:
- async 函数的返回值为 promise 对象,
- promise 对象的结果由 async 函数执行的返回值决定
await 表达式:
- await 必须写在 async 函数中
- await 右侧的表达式一般为 promise 对象
- await 返回的是 promise 成功的值
- await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
//创建一个promise对象
const p = new Promise((resolve, reject) => {
// resolve("成功啦");
reject("失败了");
});
async function main() {
try {
const result = await p;
console.log(result);
} catch (e) {
console.log(e, "e");
}
}
main();
正则表达式规则
普通字符 字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是"普通字符"。
表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
举例1:表达式 “c”,在匹配字符串 “abcde” 时,匹配结果是:成功;匹配到的内容是:“c”;匹配到的位置是:开始于2,结束于3。
举例2:表达式 “/
d
"
,
在
匹
配
字
符
串
"
a
b
c
d",在匹配字符串 "abc
d",在匹配字符串"abcde” 时,匹配结果是:成功;匹配到的内容是:“$d”;匹配到的位置是:开始于3,结束于5。
举例3:表达式 “/d/d”,在匹配 “abc123” 时,匹配的结果是:成功;匹配到的内容是:“12”;匹配到的位置是:开始于3,结束于5。
举例4:表达式 “a./d”,在匹配 “aaa100” 时,匹配的结果是:成功;匹配到的内容是:“aa1”;匹配到的位置是:开始于1,结束于4。
表达式 | 可匹配 |
---|---|
/^ | 匹配 ^ 符号本身 |
/$ | 匹配 $ 符号本身 |
/. | 匹配小数点(.)本身 |
/d | 任意一个数字,0~9 中的任意一个 |
/w | 任意一个字母或数字或下划线,也就是 AZ,az,0~9,_ 中任意一个 |
/s | 包括空格、制表符、换页符等空白字符的其中任意一个 |
. | 小数点可以匹配除了换行符(/n)以外的任意一个字符 |
自定义能够匹配 ‘多种字符’ 的表达式 使用方括号 [ ] 包含一系列字符,能够匹配其中任意一个字符。
举例1:表达式 " [bcd][bcd] " 匹配 “abc123” 时[/url],匹配的结果是:成功;匹配到的内容是:“bc”;匹配到的位置是:开始于1,结束于3。
举例2:表达式 “[^abc]” 匹配 “abc123” 时,匹配的结果是:成功;匹配到的内容是:“1”;匹配到的位置是:开始于3,结束于4。
表达式 | 可匹配 |
---|---|
[ab5@] | 匹配 “a” 或 “b” 或 “5” 或 “@” |
[^abc] | 匹配 “a”,“b”,“c” 之外的任意一个字符 |
[f-k] | 匹配 “f”~“k” 之间的任意一个字母 |
[^A-F0-3] | 匹配 “A”“F”,"0"“3” 之外的任意一个字符 |
修饰匹配次数的特殊符号
举例1:表达式 “/d+/.?/d*” 在匹配 “It costs $12.5” 时,匹配的结果是:成功;匹配到的内容是:“12.5”;匹配到的位置是:开始于10,结束于14。
举例2:表达式 “go{2,8}gle” 在匹配 “Ads by goooooogle” 时,匹配的结果是:成功;匹配到的内容是:“goooooogle”;匹配到的位置是:开始于7,结束于17。
表达式 | 作用 |
---|---|
{n} | 表达式重复n次,比如:“/w{2}” 相当于 “/w/w”;“a{5}” 相当于 “aaaaa” |
{m,n} | 表达式至少重复m次,最多重复n次,比如:"ba{1,3}"可以匹配 “ba"或"baa"或"baaa” |
{m,} | 表达式至少重复m次,比如:“/w/d{2,}“可以匹配 “a12”,”_456”,“M12344”… |
? | 匹配表达式0次或者1次,相当于 {0,1},比如:[url=http://www.regexlab.com/zh/workshop.asp?pat=a[cd]%3F&txt=a,c,d,ac,ad]"a[cd]?"可以匹配 “a”,“ac”,“ad”[/url] |
+ | 表达式至少出现1次,相当于 {1,},比如:"a+b"可以匹配 “ab”,“aab”,“aaab”… |
* | 表达式不出现或出现任意次,相当于 {0,},比如:“/^*b"可以匹配 “b”,”^^^b"… |
一些符号在表达式中代表抽象的特殊意义 | |
举例1:表达式 “^aaa” 在匹配 “xxx aaa xxx” 时,匹配结果是:失败。因为 “^” 要求与字符串开始的地方匹配,因此,只有当 “aaa” 位于字符串的开头的时候,“^aaa” 才能匹配, 比如:“aaa xxx xxx”。 | |
举例2:表达式 “aaa " 在 匹 配 " x x x a a a x x x " 时 , 匹 配 结 果 是 : 失 败 。 因 为 " " 在匹配 "xxx aaa xxx" 时,匹配结果是:失败。因为 " "在匹配"xxxaaaxxx"时,匹配结果是:失败。因为"” 要求与字符串结束的地方匹配,因此,只有当 “aaa” 位于字符串的结尾的时候,“aaa$” 才能匹配, 比如:“xxx xxx aaa”。 | |
举例3:表达式 “./b.” 在匹配 “@@@abc” 时,匹配结果是:成功;匹配到的内容是:“@a”;匹配到的位置是:开始于2,结束于4。 | |
进一步说明:“/b” 与 “^” 和 “$” 类似,本身不匹配任何字符,但是它要求它在匹配结果中所处位置的左右两边,其中一边是 “/w” 范围,另一边是 非"/w" 的范围。 | |
举例4:表达式 “/bend/b” 在匹配 “weekend,endfor,end” 时,匹配结果是:成功;匹配到的内容是:“end”;匹配到的位置是:开始于15,结束于18。 | |
表达式 | 作用 |
– | – |
^ | 与字符串开始的地方匹配,不匹配任何字符 |
$ | 与字符串结束的地方匹配,不匹配任何字符 |
/b | 匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符 |
一些符号可以影响表达式内部的子表达式之间的关系: | |
举例5:表达式 "Tom | Jack" 在匹配字符串 “I’m Tom, he is Jack” 时,匹配结果是:成功;匹配到的内容是:“Tom”;匹配到的位置是:开始于4,结束于7。匹配下一个时,匹配结果是:成功;匹配到的内容是:“Jack”;匹配到的位置时:开始于15,结束于19。 |
举例6:表达式 "(go/s*)+" 在匹配 "Let's go go go!" 时,匹配结果是:成功;匹配到内容是:"go go go";匹配到的位置是:开始于6,结束于14。
举例7:表达式 "¥(/d+/.?/d*)" 在匹配 "$10.9,¥20.5" 时,匹配的结果是:成功;匹配到的内容是:"¥20.5";匹配到的位置是:开始于6,结束于10。单独获取括号范围匹配到的内容是:"20.5"。
表达式 | 作用 |
---|---|
( ) | (1). 在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰 |
(2). 取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到 |
高级规则:
1 匹配次数中的贪婪与非贪婪 在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:“{m,n}”, “{m,}”, “?”, “*”, “+”,具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。比如,针对文本 “dxxxdxxxd”,举例如下:
贪婪模式:
表达式 | 作用 |
---|---|
(d)(/w+) | “/w+” 将匹配第一个 “d” 之后的所有字符 “xxxdxxxd” |
(d)(/w+)(d) | “/w+” 将匹配第一个 “d” 和最后一个 “d” 之间的所有字符 “xxxdxxx”。虽然 “/w+” 也能够匹配上最后一个 “d”,但是为了使整个表达式匹配成功,“/w+” 可以 “让出” 它本来能够匹配的最后一个 “d” |
ES9
对象展开
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,
在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
//rest 参数
function connect({ host, port, ...user }) {
console.log(host);
console.log(port);
console.log(user);
}
connect({
host: "127.0.0.1",
port: 3306,
username: "root",
password: "root",
type: "master",
});
//对象合并
const skillOne = {
q: "天音波",
// w: '金钟罩'
};
// ...skillOne => q: '天音波', w: '金钟罩'
const skillTwo = {
w: "金钟罩",
};
const skillThree = {
e: "天雷破",
};
const skillFour = {
r: "猛龙摆尾",
};
const mangseng = {
...skillOne,
...skillTwo,
...skillThree,
...skillFour,
};
console.log(mangseng);
正则
命名分组
//声明一个字符串
// let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
// //提取 url 与 『标签文本』
// const reg = /<a href="(.*)">(.*)<\/a>/;
// //执行
// const result = reg.exec(str);
// console.log(result);
// // console.log(result[1]);
// // console.log(result[2]);
let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
//分组命名
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result.groups.url);
console.log(result.groups.text);
断言
//声明字符串
let str = 'JS5211314你知道么555啦啦啦';
//正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
//反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str);
console.log(result);
dotAll
//dot . 元字符 除换行符以外的任意单个字符
let str = `
<ul>
<li>
<a>肖生克的救赎</a>
<p>上映日期: 1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期: 1994-07-06</p>
</li>
</ul>`;
//声明正则
// const reg = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/;
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
//执行匹配
// const result = reg.exec(str);
let result;
let data = [];
while(result = reg.exec(str)){
data.push({title: result[1], time: result[2]});
}
//输出结果
console.log(data);