ES6学习笔记
1.什么是ECMA?
ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 Ecma 国际;
- ECMAScript:ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言;
- 谁在维护 ECMA-262:TC39(Technical Committee 39)是推进 ECMAScript 发展的委员会。其会员都是公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39 定期召开会议,会议由会员公司的代表与特邀专家出席;
- 为什么要学习 ES6:ES6 的版本变动内容最多,具有里程碑意义;ES6 加入许多新的语法特性,编程实现更简单、高效;ES6 是前端发展趋势,就业必备技能;
-
ES6 兼容性:查看网址:http://kangax.github.io/compat-table/es6
2.let 关键字
// let关键字使用示例: let a;// 单个声明 let b,c,d; // 批量声明 let e = 100; // 单个声明并赋值 let f = 521, g = 'iloveyou', h = []; // 批量声明并赋值
- 变量不允许重复声明;
// 1. 不允许重复声明; let dog = "狗"; let dog = "狗"; // 报错:Uncaught SyntaxError: Identifier 'dog' has already been declared
- 块儿级作用域(局部变量):只在代码块中有效;
// 2. 块儿级作用域(局部变量); { let cat = "猫"; console.log(cat); } console.log(cat); // 报错:Uncaught ReferenceError: cat is not defined
- 不存在变量提升,不允许在定义变量之前使用变量;
consloe.log(son); let son=15;
- 不影响作用域链;什么是作用域链:就是代码块内有代码块,上级代码块中的局部变量下级可用。
3.const 关键字
- 声明必须赋初始值;
- 标识符一般为大写(习惯);
- 不允许重复声明;
- 值不允许修改:对数组元素的修改和对对象内部的修改是可以的(数组和对象存的是引用地址);
- 块儿级作用域(局部变量);
注意:声明对象类型使用 const,非对象类型声明选择 let;
4.变量的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值;
- 数组的解构赋值:
const F4 = ["大哥","二哥","三哥","四哥"]; let [a,b,c,d] = F4; // 这就相当于我们声明4个变量a,b,c,d,其值分别对应"大哥","二哥","三哥","四哥" console.log(a + b + c + d); // 大哥二哥三哥四哥
- 对象的解构赋值:
const F3 = { name : "大哥", age : 22, sex : "男", xiaopin : function(){ // 常用 console.log("我会演小品!"); } } let {name,age,sex,xiaopin} = F3; // 注意解构对象这里用的是{} console.log(name + age + sex + xiaopin); // 大哥22男 xiaopin(); // 此方法可以正常调用
5.模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识【esc下方的按键】,特点:
- 字符串中可以出现换行符;
- 可以使用 ${xxx} 形式引用变量
声明字符串的方法:单引号('')、双引号("")、反引号(``)
5.1声明
let string = `我也一个字符串哦!`; console.log(string);
5.2内容中直接出现换行符
// 特性 // 1、字符串中可以出现换行符 let str = `<ul> <li>大哥</li> <li>二哥</li> <li>三哥</li> <li>四哥</li> </ul>`; console.log(str);
5.3变量拼接
let s = "大哥"; let out = `${s}是我最大的榜样!`; console.log(out);
6.简化对象写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁;
// 变量和函数 let name = "訾博"; let change = function(){ console.log("活着就是为了改变世界!"); } //创建对象 const school = { // 完整写法 // name:name, // change:change // 简化写法 name, change, //声明方法原版:say: function(){console.log("123")} // 声明方法的简化 say(){ console.log("言行一致!"); } } school.change(); school.say();
7.箭头函数及其声明特点(=>)
ES6允许使用箭头(=>)定义函数,箭头函数提供了一种更加简洁的函数书写方式,箭头函数多用于匿名函数的定义;
7.1特性
- 箭头函数的this是静态的,始终指向函数声明时所在作用域下的this的值;
- 不能作为构造函数实例化对象,即箭头不能声明构造器;
- 不能使用 arguments 变量;
- 形参有且仅有一个时,可以省略小括号
<script> // 省略前 let add = (a) => { return a; } console.log(add(5)); // 省略后 let plus = b => { return b; } console.log(plus(77)); </script>
- 代码体语句只有一条的时候,可以省略花括号。并且此时return必须省略。此时语句的执行结构就是函数的返回值
// 省略前 let pow = (n) => { return n * n; }; console.log(pow(77)); // 省略后 let pow2 = n => n * n; console.log(pow(22));
7.2箭头函数实践和应用场景
- 案例1:点击2s后变色
<div></div> <script> // 需求1:点击div 2s后颜色变成粉色 let div = document.querySelector('div'); div.addEventListener('click', function() { // 解决方法1:提前保存this的值 let _this = this; // 定时器 // setTimeout(function() { // // 这里不能用this 点击之后this指向window而不是div // _this.style.background = 'pink'; // }, 2000) // 解决方法2:改成箭头函数 // 箭头函数里面this时静态的,指向的是“声明时,所在作用域下的this的值,所以指向的是div.addEventListener('click', function()的this” setTimeout(() => { // 这里不能用this 点击之后this指向window而不是div this.style.background = 'pink'; }, 2000) }) </script>
- 声明一个数组,从数组中返回偶数元素
<script> const arr = [1, 6, 9, 12, 55, 100]; // 原来 const result1 = arr.filter(function(item) { if (item % 2 === 0) { return true; } else return false; }) // 使用箭头函数后 const result2 = arr.filter(item => item % 2 === 0); console.log(result2); </script>注意:
- 箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
- 箭头函数不适合与 this 有关的回调. 事件回调, 对象的方法
<script> let div = document.querySelector('div'); div.addEventListener('click', ()=> { let _this = this; }) </script>
8.函数参数默认值设置
ES允许给函数的参数赋初始值;
//形参初始值 具有默认值的参数, 一般位置要靠后(潜规则) function add(a, b, c = 10) { return a + b + c; } let result = add(1, 2); console.log(result); // 13与解构赋值相结合:
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 })
9.rest参数
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments;参考文章:https://www.jianshu.com/p/50bcb376a419
<script> // ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments; // 1.ES5获取实参的方式 function data1() { console.log(arguments); } data1("大哥", "二哥", "三哥", "四哥"); // 2.ES6的rest参数...args,rest参数必须放在最后面 function data(a, b, ...args) { console.log(a); console.log(b); console.log(args); // fliter some every map } data("大哥", "二哥", "三哥", "四哥"); </script>
10.扩展运算符(...)
... 扩展运算符能将数组转换为逗号分隔的参数序列;
扩展运算符(spread)也是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包;
- 扩展运算符应用
<div></div> <div></div> <div></div> <script> //1. 数组的合并 情圣 误杀 唐探 const kuaizi = ['王太利', '肖央']; const fenghuang = ['曾毅', '玲花']; // 1.1传统的合并方式 // const zuixuanxiaopingguo = kuaizi.concat(fenghuang); // 1.2扩展运算符合并方式 const zuixuanxiaopingguo = [...kuaizi, ...fenghuang]; console.log(zuixuanxiaopingguo); //2. 数组的克隆 const sanzhihua = ['E', 'G', 'M']; const sanyecao = [...sanzhihua]; // ['E','G','M'] console.log(sanyecao); //3. 将伪数组转为真正的数组 const divs = document.querySelectorAll('div'); const divArr = [...divs]; console.log(divArr); // arguments </script>
11.Symbol基本使用
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型;
特点:(1)Symbol 的值是唯一的,用来解决命名冲突的问题(2)Symbol 值不能与其他数据进行运算(3)Symbol 定义的对象属性不能使用for…in循环遍历 ,但是可以使用Reflect.ownKeys 来获取对象的所有键名;
<script> //创建Symbol let s = Symbol(); console.log(s, typeof s); let s2 = Symbol('尚硅谷'); let s3 = Symbol('尚硅谷'); console.log(s2); console.log(s2 == s3); // false //Symbol.for 创建 let s4 = Symbol.for('尚硅谷'); let s5 = Symbol.for('尚硅谷'); console.log(s4); console.log(s4 == s5); // true </script>
// 常见的数据类型 // USONB you are so niubility // u undefined // s string symbol // o object // n null number // b boolean
11.1 Symbol的使用场景:给对象添加属性和方法
- 方式一
<script> // 向对象中添加方法 up down let game = { name: '俄罗斯方块', up: function() {}, down: function() {} }; // 我们要往game对象里面添加方法,但是怕game对象已经存在 // 同名方法,所以我们这时使用到了Symbol // 方式一 // 声明一个对象 let methods = { up: Symbol(), down: Symbol() }; game[methods.up] = function() { console.log("我可以改变形状"); } game[methods.down] = function() { console.log("我可以快速下降!!"); } console.log(game); </script>
- 方式二
<script> // 向对象中添加方法 up down let game = { name: '俄罗斯方块', up: function() {}, down: function() {} }; // 方式二 let youxi = { name: "狼人杀", [Symbol('say')]: function() { console.log("我可以发言") }, [Symbol('zibao')]: function() { console.log('我可以自爆'); } } console.log(youxi); </script>
- 调用
let youxi1 = { name: "狼人杀", [say]: function() { console.log("我可以发言") }, [Symbol('zibao')]: function() { console.log('我可以自爆'); } } let say = Symbol('say'); youxi1[say]();
总结:为了防止你创建和方法和对象本身的方法冲突,选择在另一个对象中用symbol创建独一无二的方法,用[]调用,不会污染本身对象中的方法
11.2 Symbol的内置属性
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行;总结:为了防止你创建和方法和对象本身的方法冲突,选择在另一个对象中用symbol创建独一无二的方法,用[]调用,不会污染本身对象中的方法
特别的: Symbol内置值的使用,都是作为某个对象类型的属性去使用;
12.迭代器
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作;
ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费;原生具备 iterator 接口的数据(可用 for of 遍历)有:Array;Arguments;Set;Map;String;TypedArray;NodeList;
<script> // 声明一个数组 const xiyou = ['唐僧', '孙悟空', '猪八戒', '沙僧']; // 使用 for...of 遍历数组 for (let v of xiyou) { console.log(v); } </script>注意:for(let v in xiyou):v指的是键名key=[0、1、2、3] ;for of遍历的是键值
12.1 工作原理:
- 创建一个指针对象,指向当前数据结构的起始位置;
- 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;
- 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;
- 每调用 next 方法返回一个包含 value 和 done 属性的对象;
注:需要自定义遍历数据的时候,要想到迭代器;😀
<script> // 声明一个数组 const xiyou = ['唐僧', '孙悟空', '猪八戒', '沙僧']; let it = xiyou[Symbol.iterator](); console.log(it); // 调用对象的next方法 console.log(it.next()); console.log(it.next()); console.log(it.next()); console.log(it.next()); console.log(it.next()); </script>
12.2自定义遍历对象
<script> const banji = { name: "终极一班", stus: ['xiaoming', 'xiaoning', 'xiaotian', 'knight'], // 1.首先加上iterator接口 [Symbol.iterator]() { // 索隐变量 对stus进行遍历 let index = 0; return { // 2.要有一个next对象 // 用箭头函数是this为静态变量 next: () => { if (index < this.stus.length) { const result = { value: this.stus[index], done: false }; index++; return result; } else { return { value: undefined, done: true } } } }; } } // 遍历这个对象 返回的是stus数组的对象 for (let v of banji) { console.log(v); } </script>
13.生成器
其实就是一个函数,生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同;
异步编程有 node fs ajax mongodb(数据库)
13.1概念区分
- 并发:计算机可以同时执行多个任务。比如单核处理器,可以采用分配时间片的方式让两个任务交替进行
- 并行:多核处理器可以真正实现同一时间执行任务
- 同步:上一个任务执行结束之后才可以执行下一个任务
- 异步:任务之间不会相互等待,在运行任务A的时候也可以执行任务b
13.2基本使用
-
命名时function和函数名中间要有一个星号
-
yield是函数代码的分隔符
<script> // 命名时function和函数名中间要有一个星号 function* gen() { console.log("hello generator"); } let iterator = gen(); console.log(iterator); //返回了迭代器对象 iterator.next(); //才输出 </script>
<script> // 命名时function和函数名中间要有一个星号 // 可以有一个yield语句 yield是函数代码的分隔符 下边代码将函数其分成了四块 function* gen() { console.log(111); yield '一只没有耳朵'; console.log(222); yield '一只没有尾部'; console.log(333); yield '真奇怪'; console.log(444); }; let iterator = gen(); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); for (let v of gen()) { console.log(v); } </script>
13.3生成器函数的参数传递
<script> function* gen2(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 it = gen2('aaaaa'); console.log(it.next()); // next方法可以传入实参 第二个next传入的是第一个yield语句的返回结果 console.log(it.next("bbbb")); // 第三个next传入的是第二个yield语句的返回结果 console.log(it.next("ccccc")); // 第四个next传入的是第三个yield语句的返回结果 console.log(it.next("dddddd")); </script>
13.4生成器实例:需求:1s后控制台输出111 再过2s后控制台输出222 再过3s后控制台输出333
- 方法一:回调地狱
// 方法一:回调地狱 setTimeout(() => { console.log(111); setTimeout(() => { console.log(222); setTimeout(() => { console.log(333); }, 3000) }, 2000) }, 1000);
- 方法二:设置多个函数
// 方法二:定义三个函数 分别完成三个任务 function one() { setTimeout(() => { console.log(111); iterator.next(); //进入two }, 1000) } function two() { setTimeout(() => { console.log(222); iterator.next(); //进入three }, 2000) } function three() { setTimeout(() => { console.log(333); iterator.next(); //结束 }, 3000) } function* gen() { console.log("开始喽"); yield one(); yield two(); yield three(); }; // 调用生成器函数 let iterator = gen(); iterator.next(); //刚开始调用“开始喽” 并进入one
13.5生成器函数实例:模拟获取:用户数据 订单数据 商品数据
<script>
function getuser() {
setTimeout(() => {
let data = "用户数据";
// 调用next方法并将数据传入
iterator.next(data);
}, 1000)
}
function getorder() {
setTimeout(() => {
let data = "订单信息";
iterator.next(data);
}, 1000)
}
function getgood() {
setTimeout(() => {
let data = "商品数据";
iterator.next(data);
}, 1000)
}
function* gen() {
let user = yield getuser();
console.log(user);
let order = yield getorder();
console.log(order);
let good = yield getgood();
console.log(good);
};
// 调用生成器函数
let iterator = gen();
iterator.next();
</script>
14.Promise
Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果;
- Promise 构造函数: Promise (excutor) {};
- Promise.prototype.then 方法:接受两个参数,且这两个参数都是function方法,如果resolve调用成功,则返回第一个参数的函数;
- Promise.prototype.catch 方法;用于指定Promise失败的回调;
<script> // 实例化 Promise对象 const p = new Promise(function(resolve, reject) { setTimeout(() => { let data = '数据库中的数据'; // 调用resolve,这个Promise 对象的状态就会变成成功 resolve(data); }, 1000); }); // 调用Promise对象的then方法,两个参数为函数 p.then(function(value) { // 调用成功 console.log(value); }, function(reason) { // 调用失败 }) </script>
数据读取失败:
<script> // 实例化 Promise对象 const p = new Promise(function(resolve, reject) { setTimeout(() => { // let data = '数据库中的数据'; // // 调用resolve,这个Promise 对象的状态就会变成成功 // resolve(data); let err = "数据读取失败"; // 调用reject,这个Promise 对象的状态就会变成成功 reject(err); }, 1000); }); // 调用Promise对象的then方法,两个参数为函数 p.then(function(value) { // 调用成功 console.log(value); }, function(reason) { // 调用失败 console.log(reason); }) </script>
14.1 Promise封装读取文件,在js文件里面,需要nonde.js知识
- 一般写法
// 1.引入fs模块 const fs = require('fs'); // 2.调用方法读取文件 fs.readFile('/resources/接口文档.md', (err, data) => { // 如果失败则抛出错误 if (err) throw err; // 如果没有出错 则输出内容 console.log(data); })
- 封装写法
const p = new Promise(function(resolve, reject) { fs.readFile('/resources/接口文档.md', (err, data) => { // 判断失败 if (err) reject(err); //如果成功 resolve(data); }) }) p.then(function(value) { console.log(value.toString()); }, function(reason) { console.log("读取失败!"); })
14.2 Promise封装Ajax请求
<script> const p = new Promise(function(resolve, reject) { // 创建对象 const xhr = new XMLHttpRequest(); // 初始化 xhr.open("GET", "https://api.apiopen.top/getJoke"); // 发送 xhr.send(); // 4、绑定事件,处理响应结果 xhr.onreadystatechange = function() { // 判断状态 if (xhr.readyState == 4) { // 判断响应状态码 200-299 if (xhr.status >= 200 && xhr.status <= 299) { // 成功 resolve(xhr.response); } else { // 失败 reject(xhr.status); } } } }) // 指定回调 p.then(function(value) { console.log(value); }, function(reason) { console.log(reason); }) </script>
14.3 Promise.prototype.then:
<script> const p = new Promise((resolve, reject) => { setTimeout(function() { resolve('用户数据'); // reject('错了'); }, 1000) }); // 注意:如果回调函数中返回的结果是 非promise 类型的数据,状态为成功,返回值为对象的成功值resolved const result = p.then(function(value) { console.log(value); // 1.返回的结果是 非promise 类型的数据 // return 1; // 2.返回对象是promise对象 此Promise对象的状态决定上面Promise对象p的状态 // return new Promise((resolve, reject) => { // // resolved // resolve('ok'); // // rejected // reject('wrong'); // }) // 3.抛出错误 // 状态:rejected // value:出错了 throw '出错了'; }, function(reason) { console.warn(reason); }); // 可以链式调用,then里面两个函数参数,可以只写一个 // p.then(value => {}, reason => {}).then(value => {}, reason => {}); // 调用then方法,then方法的返回结果是promise对象,对象的状态由回调函数的结果决定; console.log(result); </script>
14.4 Promise实践
- 回调地狱写法:容易有重名问题
// 1、引入 fs 模块 const fs = require("fs"); // 2、调用方法,读取文件 fs.readFile("resources/text.txt", (err, data1) => { fs.readFile("resources/test1.txt", (err, data2) => { fs.readFile("resources/test2.txt", (err, data3) => { let result = data1 + data2 + data3; console.log(result); }); }); });
- Promise写法:
const p = new Promise((resolve, reject) => { fs.readFile("resources/text.txt", (err, data) => { resolve(data); }); }); p.then(value => { return new Promise((resolve, reject) => { fs.readFile("resources/test1.txt", (err, data) => { resolve([value, data]); }); }) }).then(value => { return new Promise((resolve, reject) => { fs.readFile("resources/test2.txt", (err, data) => { // 存入数组 value.push(data); resolve(value); }); }) }).then(value => { console.log(value.join("\r\n")); })
14.5 catch方法
用于指定Promise失败的回调;
<script> const p = new Promise((resolve, reject) => { setTimeout(() => { // 设置 p 对象的状态为失败 ,并设置失败的值 reject("出错了"); }, 1000) }); // 方式1: p.then(function(value) {}, function(reason) { console.log(reason); }); // 方式2:算是一个语法糖,即使没有catch 用then也可以工作 p.catch(function(reason) { console.log(reason); }); </script>
15.Set集合
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法:
- size 返回集合的元素个数;
- add(value):添加某个值,返回 Set 结构本身(可以链式调用)
- delete(value):删除某个值,删除成功返回true,否则返回false
- has(value):返回一个布尔值,表示该值是否为Set的成员,有返回true,否则返回false
- clear(): 将这个Set中的所有元素删除
const mySet = new Set(['a', 'a', 'b', 1, 2, 1]) console.log(mySet) // {'a', 'b', 1, 2} myset.add('c').add({'a': 1}) //链式调用 console.log(mySet) // {'a', 'b', 1, 2, 'c', {a: 1}} console.log(mySet.size) // 6 mySet.has(2) // true
- 初始化
var set = new Set();
15.1 遍历方法
- keys():返回键名的遍历器
- values():返回键值的遍历器
- entries():返回键值对的遍历器
- forEach():使用回调函数遍历每个成员
const set = new Set(['a', 'b', 'c']) for (var item of set.keys()) { console.log(item) } // a // b // c for (var item of set.values()) { console.log(item) } // a // b // c for (var item of set.entries()) { console.log(item) } // 因为key=value // ["a", "a"] // ["b", "b"] // ["c", "c"] // 直接遍历set实例,等同于遍历set实例的values方法 for (var item of set) { console.log(item) } // a // b // c set.forEach(function(value, key) { console.log(key + ' : ' + value) }) // a: a // b: b // c: c
15.2 数组的操作【数组去重、交集、并集、差集】
- filter函数【过滤】:如果返回的是true 则将这个元素保留在数组中,如果返回的是false,则要将这个元素删除
- 数组去重
<script> let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1, 8, 9, 10]; let arr2 = [4, 3, 2, 1, 7]; // 数组去重 let result1 = [...new Set(arr)]; console.log(result1); // 交集 let result2 = [...new Set(arr)].filter(item => { let s2 = new Set(arr2); if (s2.has(item)) { return true; } else { return false; } }) console.log(result2); // 并集 let result3 = [...new Set([...arr, ...arr2])]; console.log(result3); //差集 求arr里面有 arr2里面没有的;对arr2里面取反 let result4 = [...new Set(arr)].filter(item => !(new Set(arr2).has(item))); console.log(result4); </script>
16.Map
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历;
Map 的属性和方法:
- size 返回 Map 的元素个数;
- set(key, val): 向Map中添加新元素
- get(key): 通过"键值"查找特定的数值并返回
- has(key): 判断Map对象中是否有Key所对应的值,有返回true,否则返回false
- delete(key): 通过"键值"从Map中移除对应的数据
- clear(): 将这个Map中的所有元素删除
const map = new Map([ ['Amy', 11], ['Sam', 12] ]); console.log(map); // {"Amy" => 11, "Sam" => 12} console.log(map.get('Amy')); // 11 const map2 = new Map([ ['Cindy', 13] ]) const map3 = new Map(map2); console.log(map3.get('Cindy')); // 13 console.log(map3.has('Cindy')); // true map3.set('Divid', 15) console.log(map3.get('Divid')); // 15
16.1 循环遍历
- keys():返回键名的遍历器
- values():返回键值的遍历器
- entries():返回键值对的遍历器
- forEach():使用回调函数遍历每个成员
const map = new Map([ ['Amy', 11], ['Sam', 12] ]) for (var key of map.keys()) { console.log(key) } // "Amy" // "Sam" for (var value of map.values()) { console.log(value) } // 11 // 12 for (var item of map.entries()) { console.log(item) } // ['Amy', 11], // ['Sam', 12] // 方法一: for (var [key, value] of map.entries()) { console.log(key, value) } // "Amy" 11 // "Sam" 12 // 方法二:for...of...遍历map等同于使用map.entries() // 方法一和方法二的输出结果一样 for (var [key, value] of map) { console.log(key, value); } // "Amy" 11 // "Sam" 12
16.2Map与Object区别
- Map中的键值是有序的,而添加到对象中的键则不是
- Map的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算
- Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突
17.Class类
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已;
- ES5通过实例化创造对象
<script> function Phone(brand, price) { this.brand = brand; this.price = price; } // 添加方法 Phone.prototype.call = function() { console.log("打电话"); } // 实例化对象 let Hawei = new Phone('华为', 5999); Hawei.call(); console.log(Hawei); </script>
- ES6
<script> class Phone { // 构造方法 名字不能修改 会自动执行 constructor(brand, price) { this.brand = brand; this.price = price; } // ES6定义方法必须使用该语法,不能使用ES5的对象完整形式 call() { console.log("我可以打电话"); } } let Hawei = new Phone('华为', 5999); console.log(Hawei); </script>
17.1 静态成员
//ES5 <script> function Phone() { } Phone.name = '手机'; Phone.change = function() { console.log("我可以改变世界"); } let nokia = new Phone(); console.log(nokia.name); // undefined //nokia.change(); // 报错:Uncaught TypeError: nokia.change is not a function // 注意:实例对象和函数对象的属性是不相通的 Phone.prototype.size = '5.5'; console.log(nokia.size); </script>
//ES6 <script> // ES6写法 class Phone { // 静态属性 属于类 而不属于实例对象 // 静态属性通过类名.方法名访问 static name = "手机"; static change() { console.log("我可以改变世界!"); } } let nokia = new Phone(); console.log(nokia.name); //undefined console.log(Phone.name); //手机 Phone.change(); </script>
17.2 对象继承
- ES5
<script> // 手机 function Phone(brand, price) { this.brand = brand; this.price = price; } // 添加方法 Phone.prototype.call = function() { console.log("打电话"); }; // 智能手机 function SmartPhone(brand, price, color, size) { Phone.call(this, brand, price); this.color = color; this.size = size; } // 设置子集构造函数的原型 SmartPhone.prototype = new Phone; SmartPhone.prototype.constructor = SmartPhone; // 声明子类方法 SmartPhone.prototype.photo = function() { console.log("拍照"); } SmartPhone.prototype.game = function() { console.log("游戏"); } // 实例化对象 let chuizi = new SmartPhone('华为', 5999, 'black', '5.5'); console.log(chuizi); </script>
- ES6
<script> class Phone { constructor(brand, price) { this.brand = brand; this.price = price; } call() { console.log("我可以打电话"); } } class SmartPhone extends Phone { constructor(brand, price, color, size) { super(brand, price); this.color = color; this.size = size; } photo() { console.log("拍照"); } game() { console.log("游戏"); } } let chuizi = new SmartPhone('小米', 1999, 'black', '5.5'); console.log(chuizi);</script>chuizi.call();chuizi.photo();chuizi.game();
17.3 子类对父类的重写
<script> class Phone { constructor(brand, price) { this.brand = brand; this.price = price; } call() { console.log("我可以打电话"); } } class SmartPhone extends Phone { constructor(brand, price, color, size) { super(brand, price); this.color = color; this.size = size; } photo() { console.log("拍照"); } game() { console.log("游戏"); } // 就近原则 call() { console.log("我对父类进行重写了"); } } let chuizi = new SmartPhone('小米', 1999, 'black', '5.5'); chuizi.call(); </script>
17.4 class的getter和setter设置
<script> // class中的getter和setter设置 class Phone { get price() { console.log("价格属性被读取了!"); // 返回值 return 123; } // set里面要设置一个参数 set price(value) { console.log("价格属性被修改了!"); } } // 实例化对象 let s = new Phone(); console.log(s.price); // 返回值 s.price = 2999; </script>
17.5 数值扩展
- Number.EPSILON:Number.EPSILON 是 JavaScript 表示的最小精度;EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16;
-
二进制和八进制:ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示;
-
Number.isFinite() 与 Number.isNaN() :Number.isFinite() 用来检查一个数值是否为有限的;Number.isNaN() 用来检查一个值是否为 NaN;
-
Number.parseInt() 与 Number.parseFloat():字符串转成整数,ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变;
-
Math.trunc:用于去除一个数的小数部分,返回整数部分
-
Number.isInteger:Number.isInteger() 用来判断一个数值是否为整数;
<script> // 数值扩展 // 0. Number.EPSILON 是 JavaScript 表示的最小精度 // EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16 // function equal(a, b){ // return Math.abs(a-b) < Number.EPSILON; // } console.log("0、Number.EPSILON 是 JavaScript 表示的最小精度"); // 箭头函数简化写法 equal = (a, b) => Math.abs(a-b) < Number.EPSILON; console.log(0.1 + 0.2); console.log(0.1 + 0.2 === 0.3); // false console.log(equal(0.1 + 0.2, 0.3)); // true // 1. 二进制和八进制 console.log("1、二进制和八进制"); let b = 0b1010; let o = 0o777; let d = 100; let x = 0xff; console.log(x); // 2. Number.isFinite 检测一个数值是否为有限数 console.log("2、Number.isFinite 检测一个数值是否为有限数"); console.log(Number.isFinite(100)); console.log(Number.isFinite(100 / 0)); console.log(Number.isFinite(Infinity)); // 3. Number.isNaN 检测一个数值是否为 NaN console.log("3. Number.isNaN 检测一个数值是否为 NaN"); console.log(Number.isNaN(123)); // 4. Number.parseInt Number.parseFloat字符串转整数 console.log("4. Number.parseInt Number.parseFloat字符串转整数"); console.log(Number.parseInt('5211314love')); console.log(Number.parseFloat('3.1415926神奇')); // 5. Number.isInteger 判断一个数是否为整数 console.log("5. Number.isInteger 判断一个数是否为整数"); console.log(Number.isInteger(5)); console.log(Number.isInteger(2.5)); // 6. Math.trunc 将数字的小数部分抹掉 console.log("6. Math.trunc 将数字的小数部分抹掉 "); console.log(Math.trunc(3.5)); // 7. Math.sign 判断一个数到底为正数 负数 还是零 console.log("7. Math.sign 判断一个数到底为正数 负数 还是零"); console.log(Math.sign(100)); console.log(Math.sign(0)); console.log(Math.sign(-20000)); </script>
17.6 对象方法扩展
ES6 新增了一些 Object 对象的方法:
- Object.is 比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN);
- Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象;
- proto、setPrototypeOf、 setPrototypeOf 可以直接设置对象的原型;
18.模块化
(1)模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来;
(2)好处:- 防止命名冲突;
- 代码复用;
- 高维护性;
ES6 之前的模块化规范有:
(4)ES6 模块化语法:模块功能主要由两个命令构成:export 和 import;
- CommonJS => NodeJS、Browserify;
- AMD => requireJS;
- CMD => seaJS;
- export 命令用于规定模块的对外接口(导出模块);
- import 命令用于输入其他模块提供的功能(导入模块);
18.1暴露数据语法
17test.js(导出模块)
-
分别暴露:在想要暴露的数据上export一下
export let school = "尚硅谷"; export function teach() { console.log("我们可以教你开发技术!"); }
- 统一暴露
let school = "尚硅谷"; function teach() { console.log("我们可以教你开发技术!"); } export { school, teach };
- 默认暴露
export default { school: 'At', change: function() { console.log("我们可以改变你"); } }在html文件中引入
<script type="module"> import * as m1 from "./17test.js"; console.log(m1); //默认暴露 m1.default.change() </script>
18.3引入数据语法
- 通用导入形式
<script type="module"> import * as m1 from "./17test.js"; console.log(m1); //默认暴露 m1.default.change() </script>
- 解构赋值形式
<script type="module"> import { school, teach } from "./17test.js"; //给school和teach设置了别名 import { school as guigu, teach as fangfa } from "./17test.js"; console.log(school); console.log(guigu); </script>
- 默认形式
<script type="module"> // 要给default设置一个别名 import { default as m3 } from "./17test.js"; console.log(m3); </script>
- 简便形式 针对默认暴露
<script type="module"> import m3 from "./17test.js"; console.log(m3); </script>
18.4 使用模块化的另一种形式
- 将原本写在html中的js整合到一个app.js文件中
import * as m from "./m.js"; console.log(m); console.log(m.school); m.teach();
- 然后在html中执行js文件
<html> <head> <meta charset="utf-8"> <title>使用模块化的另一种方式</title> </head> <body> <script src="./js/app.js" type="module"></script> </body> </html>
19.原型和原型链
19.1 构造函数原型 prototype
构造函数通过原型分配的函数是所有对象所共享的。
JS规定,每一个构造函数都有一个prototype属性,指向另一个对象。prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。
我们可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法
<script> function Star(name, age) { this.name = name; this.age = age; } Star.prototype.sing = function() { console.log("我会唱歌"); } var ldh = new Star("刘德华", 19); var zxy = new Star("张学友", 19); ldh.sing(); zxy.sing(); </script>
- 原型是什么?一个对象,我们也称prototype为一个原型对象
- 原型作用?共享方法
- 一般来说,我们的公共属性定义到构造函数里面
- 公共方法放到原型对象身上,所以可以实现共享
- 对象身上,系统自己添加一个__proto__,指向我们构造函数的原型对象prototype,__proto__对象原型和原型对象prototype是等价的。
19.2 构造函数
- 对象原型(__ proto __)和构造函数(prototype)原型对象里面都有一个属性constructor属性,constructor我们称为构造函数,因为他指向会构造函数本身。
- constructor 主要用于记录该对象引用那个构造函数,它可以让原型对象重新指向原来的构造函数
- 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,那么就必须手动利用constructor指回原来的函数
<script> function Star(name, age) { this.name = name; this.age = age; } Star.prototype = { // 如果有很多个所有对象所共享的方法,那么我们可以通过给Star的原型里面覆盖的方法进行编写函数 // 但是把原来的构造函数覆盖掉 // 所以我们要进行如下操作:constructer: Star,重新指回Star constructer: Star, sing: function() { console.log("我会唱歌"); }, movie: function() { console.log("我会演电影"); } } var ldh = new Star("刘德华", 19); var zxy = new Star("张学友", 19); console.log(Star.prototype); console.log(ldh.__proto__); console.log(Star.prototype === ldh.__proto__); //true </script>
19.3 三者之间的关系
19.4原型链
成员的查找规则:按照原型链进行查找
- 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
- 如果没有就查找它的原型(也就是__ proto __指向的prototype原型对象)。
- 如果还没有就查找原型对象的原型(Object的原型对象)。
- 以此类推一直找到Object为止(null)
- __ proto __ 对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线
19.5原型对象this指向
(1)类里面的 this指向问题- 在 ES 6 中类没有变量提升 所以必须先定义类 才能通过实例化对象
- 类里面的共有的属性和方法一定要加this使用
- constructor 【构造函数】里面的this指向实例对象 方法里面的this指向这个方法的调用者
<script> function Star(name, age) { this.name = name; this.age = age; } var that; Star.prototype.sing = function() { console.log("我会唱歌"); that = this } var ldh = new Star("刘德华", 19); // 在构造函数中,里面的this指向的是对象实例ldh ldh.sing(); console.log(that === ldh); //true // 原型对象函数里面的this指向实例对象 ldh </script>
19.6扩展内置内向
可以通过原型对象,对原来的内置对象进行扩展自定义的方法,比如给对象增加自定义求偶数和的功能。
(※)注意:数组和字符内置对象不能给原型对象覆盖操作 Array.prototype = {} , 只能是 Array.prototype.xxx = function(){}的方法。
19.7 call函数
ES6之前没有提供extends集成,所以我们可以通过构造函数+原型对象的方法模拟继承,被称为组合继承。
call():调用这个函数,并且修改函数运行时的this指向
<script> function fn(x, y) { console.log("1231213"); console.log(this); console.log(x + y); } var o = { name: 'andy' }; // fn();//可以调用函数 //1.call可以调用函数 // fn.call(); //2. call可以改变函数this指向 此时这个函数this指向了o这个对象 fn.call(o, 1, 2); </script>
19.8 借用构造函数继承父类型属性
- 核心原理:通过call() 把父类型的this 指向子类型的this , 这样就可以实现子类型继承父类型的属性。
- 如果子构造函数调用父构造函数的话,一定要把父构造函数里面的this指向子构造函数里面的this
<script> function Father(name, age) { this.name = name; this.age = age; } function Son(name, age) { // this指向子构造函数的对象实例 // 调用父亲构造函数,将父构造函数的this指向子构造函数 Father.call(this, name, age); } var ldh = new Son("刘德华", 19); console.log(ldh); </script>
19.9 借用构造函数继承父类型方法
<script> function Father(name, age) { this.name = name; this.age = age; } Father.prototype.money = function() { console.log(100); } function Son(name, age) { // this指向子构造函数的对象实例 // 调用父亲构造函数,将父构造函数的this指向子构造函数 Father.call(this, name, age); } // Son.prototype = Father.prototype; 这样赋值会有问题,如果直接修改了子原型对象,父原型对象也会改变 // 所以我们要给Son.prototype覆盖一个新的对象Father,再在Father的基础上编辑子方法.这样怎么修改子原型对象都不会影响父原型对象了 Son.prototype = new Father(); // 子构造函数专门的方法 Son.prototype.exam = function() { console.log("孩子要考试"); } var ldh = new Son("刘德华", 19); console.log(ldh); </script>
20.ES5 中新增的方法
迭(die)代(遍历)方法:forEach()、map()、filter()、 some()、every()- foreach()
var arr = [1, 2, 3]; arr.forEach(function(value, index, array) { console.log(value); //数组元素 console.log(index); //元素索引号 console.log(array); //数组本身 })
- filter():创建一个新的数组,新数组中的元素时通过检查指定数组中符合条件的所有元素,主要用于筛选数组,注意它直接返回一个新数组
var arr = [12, 62, 43]; var newarr = arr.filter(function(value, index) { if (value >= 20) return true; else return false; }) console.log(newarr);
- some():用于检测数组中的元素是否满足指定条件 通俗点 查找数组中是否有满足条件的元素,它返回值是布尔值,如果查找到这个元素,就返回true,如果查找不到就返回false
var arr = ['red', 'yellow', 'med']; var flag = arr.some(function(value) { return value === 'red'; }); console.log(flag); //true
- trim():会从一个字符串的两端删除空白字符
var str = ' andy '; var str1 = str.trim(); console.log(str); console.log(str1);
21.闭包
- 闭包(closure) 指有权访问另一个函数作用域中变量的函数。
- 简单理解就是,一个作用域可以访问另外一个函数内部的局部变量,闭包本身就是一个函数
function fn() { var num = 10; function fun() { // fun可以使用fn console.log(num); } fun(); }
// vn外边的作用域也可以访问vn内部的局部变量 function vn() { var num = 10; // function vun() { // console.log(num); // } // return vun; return function() { console.log(num); } } var v = vn(); // 类似于 // var f = function vun() { // console.log(num); // } // 外部可以使用vn内部变量num v();
-
闭包是什么?
闭包是一个函数(一个作用域可以访问另外一个函数的局部变量) -
闭包的作用是什么?
延伸变量的作用范围
21.1 闭包案例:点击li打印当前索引号
<body> <ul class="nav"> <li>123</li> <li>546</li> <li>789</li> <li>498465</li> </ul> <script> var lis = document.querySelector(".nav").querySelectorAll('li'); for (var i = 0; i < lis.length; i++) { // 以前做法:新建一个index // lis[i].index = i; // lis[i].onclick = function() { // console.log(this.index); // } // 现在:利用闭包的方式得到当前li的索引号 // 利用for循环,对每一个i先创建"立即执行函数",参数是下标i // 同时"立即执行函数"也成为了小闭包,因为立即执行函数黎曼任何一个函数都可以使用i这个变量 (function(i) { lis[i].onclick = function() { console.log(i); } })(i) } </script> </body>
21.2 闭包案例:3s之后 打印所有li元素的内容
<body> <ul class="nav"> <li>123</li> <li>546</li> <li>789</li> <li>498465</li> </ul> <script> var lis = document.querySelector(".nav").querySelectorAll('li'); for (var i = 0; i < lis.length; i++) { (function(i) { setTimeout(function() { console.log(lis[i].innerHTML); }, 3000); })(i); } </script> </body>
21.3 闭包案例:计算打车价格
- 3公里以内13元,之后每多1公里5元,用户输入公里数就可以计算打车价格
- 如果拥堵 就额外收10元
<script> var car = (function() { var qibujia = 13; var zongjia = 0; return { price: function(n) { if (n <= 3) { zongjia = qibujia; } else { zongjia = qibujia + (n - 3) * 5; } return zongjia; }, yongdu: function(flag) { return flag ? zongjia + 10 : zongjia; } } })(); console.log(car.price(5)); console.log(car.yongdu(true)); </script>
22.浅拷贝和深拷贝
- 浅拷贝只是拷贝一层,更深层次对象级别的值拷贝引用,修改o里面的msg也会影响obj里面的msg
- 深拷贝拷贝多层,每一级别的数据都会拷贝。
<script> var o = {}; var obj = { nam: 13, age: 18, masg: { aggg: 18 } }; function deepCopy(newl, old) { for (var k in old) { // 判断属性值属于哪种数据类型 // 1.获取属性值 var item = old[k]; // 2.判断是否是数组,数组写在Object上边 if (item instanceof Array) { newl[k] = []; deepCopy(newl[k], item); } // 3.判断是否是对象 else if (item instanceof Object) { newl[k] = {}; deepCopy(newl[k], item); } // 4.属于简单数据类型 else { newl[k] = item; } } } deepCopy(o, obj); console.log(o); </script>
- Object.assign(target, …sources) ES6新增方法可以浅拷贝
var o = {}; var obj = { nam: 13, age: 18 }; Object.assign(o, obj);
23.正则表达式
- 概述:正则表达式(Regular Expression) 是用于匹配字符串中字符组合的模式。
- 在 JavaScript中,正则表达式也是对象正则表通常被用来检索、替换那些符合某个模式(规则)的文本,列如验证表单:用户名表单只能输入英文字母、数字或下划线, 昵称输入框中可以输入中文(匹配)。
- 此外,正则表达式还常用于过滤掉网页内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等。
-
其他语言也会使用正则表达式,本阶段我主要是利用 JavaScript正则表达式完成表单验证
23.1 创建正则表达式
// 1RegEXP var regexp=new RegExp(/123/); console.log(regexp); // 2字面量 var rg=/123/;
23.2检测正则表达式 test
test() 正则对象方法,用于检测字符串是否符合该规则,该对象会返回 true 或 false 其参数是测试字符串。
var rg = /123/; console.log(rg.test(123)); //true console.log(rg.test('abc')); //false
23.3正则表达式的特殊字符
- 一个正则表达式可以由简单的字符构成,比如/abc/, 也可以是简单和特殊字符的组合,比如/ab*c/. 其中特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号,如^、$、+等
-
特殊字符非常多,可以参考:
- MDN
- jQuery 手册
- 正则测试工具
- 边界符
// 边界符 以XX结尾$ 以XX开头^ var rg = /abc/; // /abc/表示只要这个字符串包含了abc这个字符串都是true console.log(rg.test('abccccc')); //true console.log(rg.test('abc')); //true console.log(rg.test('bvbabc')); //true var rg2 = /^abc/; // /^abc/表示要以abc开头 console.log(rg2.test('abccccc')); //true console.log(rg2.test('abc')); //true console.log(rg2.test('bvbabc')); //false var rg3 = /^abc$/; // /^abc&/表示要以abc开头,以abc结尾,所以这个就是精确匹配必须是abc console.log(rg3.test('abccccc')); //false console.log(rg3.test('abc')); //true console.log(rg3.test('abcabc')); //false var rg4 = /abc$/; // /^abc/表示要以abc结尾 console.log(rg4.test('abccccc')); //false console.log(rg4.test('abc')); //true console.log(rg4.test('bvbabc')); //true
- 字符类[]
// 字符类:[]表示一系列字符可供选择 只要匹配其中一个就可以了 var rg = /[abc]/; //只要包含a 或者b 或者c都会返回true console.log(rg.test('abc')); //true console.log(rg.test('andy')); //true console.log(rg.test('color')); //true console.log(rg.test('mh')); //false var rg2 = /^[abc]$/; //三选一 只有是a 或者 只有是b 或者 只有是c 这三个字母才返回true console.log(rg2.test('a')); //true console.log(rg2.test('aa')); //false console.log(rg2.test('b')); //true console.log(rg2.test('mh')); //false var rg3 = /^[a-z]$/; //[-]26个英文字母任何一个字母都会返回true console.log(rg3.test('z')); //true console.log(rg3.test('Z')); //false 大写也不行
- 字符组合
// 字符组合 var rg4 = /^[a-zA-Z0-9_]$/; //限制用户只能输入英文字母和数字和下划线 console.log(rg4.test('_')); //true
- 在[]里面的^表示取反
var rg5 = /^[^a-zA-Z0-9_]$/; //用户不能输入英文字母和数字和下划线 console.log(rg5.test('_')); //false
- 量词符
// *:代表大于等于0 可以出现0次或者很多次 var re = /^a*$/; console.log(re.test('')); //true console.log(re.test('aaa')); //true console.log(re.test('a')); //true // +:代表大于等于1 可以出现1次或者很多次 var re1 = /^a+$/; console.log(re1.test('')); //false console.log(re1.test('aaa')); //true console.log(re1.test('a')); //true //?:代表 1||0 只有出现一次或者一次都不出现才对 var re2 = /^a?$/; console.log(re2.test('')); //true console.log(re2.test('aaa')); //fasle console.log(re2.test('a')); //true //{3}:代表重复三次 var re3 = /^a{3}$/; console.log(re3.test('')); //false console.log(re3.test('aaa')); //true console.log(re3.test('a')); //false //{3,}:代表重复大于等于三次 var re4 = /^a{3,}$/; console.log(re4.test('')); //false console.log(re4.test('aaa')); //true console.log(re4.test('aaaaaa')); //true console.log(re4.test('a')); //false //{3,8}:代表重复大于等于三次,小于等于8次 var re5 = /^a{3,}$/; console.log(re5.test('')); //false console.log(re5.test('aaaa')); //true console.log(re5.test('aaaaaaaaaaaaaaaaaaa')); //false console.log(re5.test('a')); //false
//循环次数之间不能有空格 var rg4 = /^[a-zA-Z0-9_]{6,16}$/;
- 括号总结
(2)中括号 字符集合。匹配方括号中的任意字符
(3)小括号 表示优先级
// 让c重复6次 var rg4 = /^abc{6}$/; // 让abc重复6次 var rg4 = /^(abc){6}$/;
- 在线测试工具
23.4正则表达式预定义类
// 座机验证:010-12345678 或者(|) 0535-1234567 var regg=/^\d{3}-\d{8} | \d{4}-\d{7}$/;
24.5 正则替换,用于敏感词替换
- replace 替换:replace() 方法可以实现替换字符串的操作,用来替换的参数可以是一个字符串或者一个正则表达式。
stringObject.replace(regexp/substr,replacement)
- 第一个参数:被替换的字符串 或者 正则表达式
- 第二个参数:替换的字符串
- 返回值是一个替换完毕的新字符串
- 正则表达式参数
/表达式/[switch]switch (也称为修饰符) 按照什么样的模式来匹配,有三种值:
- g【global】 : 全局匹配
- i 【ignore】: 忽略大小写
- gi : 全局匹配+忽略大小写