JavaScript高级
-
面向对象是把事务分解成一个个对象,然后由对象之间分工与合作。
-
-
在面向对象程序开发思想中,每个对象都是功能中心,具有明确分工。
-
面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型项目
面向的特点:
-
封装性
-
继承性
-
多态性
ES6中的类和对象
创建类
语法:
class name {
// class body
}
创建实例 : var xx = new name();
类constructor 构造函数
constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法。如果没有显示定义,类内部会自动创建一个constructor()
<script>
class SEEr {
constructor(med,aeer) {
this.med = med
this.aeer = aeer
}
}
var liu = new SEEr('张学友',23)
var li = new SEEr('张学',233)
console.log(liu);//SEEr {med: '张学友', aeer: 23}
console.log(li.med); //张学
</script>
-
通过class关键词创建类,类名定义首字母大写
-
类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
-
constructor函数只要new生成实例,就会自动调用这个函数,如果不写,类里面也会自动生成这个函数
-
生成实例 new 不能省略
类添加方法
语法:
class Person {
constructor (name,age) { // constructor 构造器或者构造函数
this.name = name;
this.age = age;
}
say() {
console.log(this.name + '你好');
}
}
<script>
class SEEr {
constructor(med,aeer) {
this.med = med
this.aeer = aeer
}
sing(ge) {
console.log(this.med + ge);
}
}
var liu = new SEEr('张学友',23)
var li = new SEEr('张学',233)
console.log(liu);
console.log(li.med);
liu.sing('冰雨')
li.sing('李香兰')
</script>
-
类里面所有的函数不需要写function
-
多个函数方法之间不需要添加逗号分隔
类的继承
语法:
class Father {
}
class Son extends Father { //子类继承父类
}
super 关键字
super 关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数
注意:子类在构造函数中使用super,必须放到this前面(必须先调用父类的构造方法,在使用子类构造方法)
<script>
class Father {
constructor(x,y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor(x, y) {
super(x, y);
}
}
var son = new Son(1,3)
son.sum();
</script>
-
继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
-
继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有就执行父类这个方法(就近原则)
使用类的注意点
-
在ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象
-
类里面到共有的属性和方法一定要加this使用
构造函数
JavaScript的构造函数中可以添加一些成员,可以在构造函数本身上添加,也可以在构造函数内部的this上添加。通过这两种方式添加的成员,就分别是静态成员和实例成员
-
静态成员:在构造函数本上添加的成员称为静态成员,只能由构造函数本身来访问
-
实例成员:在构造函数内部创建的对象成员称为实例成员,只能由实例化的对象来访问
函数内this的指向
调用方式 | this指向 |
---|---|
普通函数调用 | window |
构造函数调用 | 实例对象 原型对象里面的方法也指向实例对象 |
对象方法调用 | 该方法所属对象 |
事件绑定方法 | 绑定事件对象 |
定时器函数 | window |
立即执行函数 | window |
改变函数内部this指向
常用的有 bind() call() apply()
1.call方法
call()方法调用一个对象,并改变函数的this指向
fun.call(thisArg, arg1, arg2,...)
thisArg :在fun函数运行时指定的this值
arg1,arg2:传递的其他参数
返回值就是函数的返回值,因为它就是调用函数
2.apply方法
apply()方法调用一个对象,并改变函数的this指向
fun.apply(thisArg, [argsArray])
argsArray:传递的值,必须包含在数组里面
3.bind方法
不会调用函数,但能改变函数内部this指向
fun.bind(thisArg,arg1,arg2)
thisArg :在fun函数运行时指定的this值
arg1,arg2:传递的其他参数
返回由指定的this值和初始化参数改造的原函数拷贝
call apply bind 总结
相同点:都可以改变函数内部的this指向
区别点:
1.call和apply会调用函数,并且改变函数内部this指向
2.call和apply传递的参数不一样,call传递参数aru1,aru2形式apply必须数组形式【arg】
3.bind不会调用函数,可以改变函数内部this指向
主要应用场景:
1.call经常做继承
2.apply经常跟数组有关系,比如借助于数学对象实现数组最大最小值
3.bind不调用函数,但是还想改变this,比如改变定时器内部的this指向
严格模式
JavaScript除了提供正常模式外,还提供了严格模式(strict mode)。ES5的严格模式是采用具有限制性JavaScript变体的一种方式,即在严格的条件下运行JS代码。
严格模式在IE10以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。
严格模式对正常的JavaScript语意做了一些更改:
1.消除了JavaScript语法中的一些不合理,不严谨之处,减少了一些怪异行为。
2.消除代码运行的一些不安全之处,保证代码运行的安全。
3.提高编译器效率,增加运行速度。
4.禁用了在ECMAScript的未来版本中可能会定义的一些语法,为未来新版本的JavaScripyt做好铺垫。比如一些保留字如:class,enum,export,extends,import,super不能做变量名
开启严格模式
严格模式可以应用到整个脚本或个别函数中。因此在使用时,我们可以将严格模式分为脚本开启严格模式和为函数开启严格模式两种情况。
1.为脚本开启严格模式
需要在所有语句之前放一个特定语句“use strict”;(或‘use strict’;)。
<script>
"use strict";
console.log("这是严格模式。")
<script>
因为“use strict”加了引号,所以老版本的浏览器会把它当做一行普通字符串而忽略
-
有的script基本上是严格模式,有的script脚本是正常模式,这样不利于文件合并,所以可以将整个脚本文件放在一个立即执行的匿名函数之中。这样独立创建一个作用域而不影响其他script脚本文件。
<script>
(function(){
"use strict";
var num = 10;
function fn() {}
})();
<script>
2.为函数开启严格模式
要给某个函数开启严格模式,需要把“use strict”;(或‘use strict’;)声明放在函数体所有语句之前。
function fn() {
"use strict"
return"这是严格模式。";
}
将“use strict”放在函数体的第一行,则整个函数以“严格模式”运行
严格模式中的变化
1.变量规定
-
在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,变量都必须先用var命令声明,然后在使用
-
严禁删除已经声明变量,例如,delete x; 语法是错误的。
2.严格模式下this指向问题
-
以前在全局作用域函数中的this指向window对象
-
严格模式下全局作用域中函数的this是undefined
-
以前构造函数时不加new也可以调用当普通函数,this指向全局对象
-
严格模式下,如果构造函数不加new调用,this指向的是undefined如果给他赋值则会报错
-
new实例化的构造函数指向创建的对象实例
-
定时器this还是指向window
-
事件、对象还是指向调用者
3.函数变化
-
函数不能有重名的参数
-
函数必须声明在顶层新版本的JavaScript会引入“块级作用域”(ES6中已引入)。为了与新版本接轨,不允许在非函数的代码块内声明函数。
高阶函数
高阶函数是对其他函数进行操作的函数,他接收函数作为参数或将函数作为返回值输出。
<script>
function fn(callback) {
callback&&callback();
}
fn(function() {alert('hi')})
</script>
<script>
function fn() {
return function() {}
}
fn()
</script>
此时fn就是一个高阶函数,函数也是一种数据类型,同样可以作为参数,传递给另一个参数使用。最典型的就是作为回调函数。同理函数也可以作为返回值传递回来。
闭包
闭包指有权访问另一个函数作用域中变量的函数,简单理解就是,一个作用域可以访问另一外一个函数内部的局部变量
<script>
function fn1() {
var num = 10;
function fn2() { //fn2是闭包
console.log(num); //10
}
fn2()
}
fn()
</script>
递归
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。 简单理解:函数内部自己调用自己, 这个函数就是递归函数 递归函数的作用和循环效果一样 由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return。
浅拷贝,深拷贝
浅拷贝:只是拷贝一层,更深层次对象级别的只拷贝引用
深拷贝:拷贝多层,每一级别的数据都会拷贝
Object.assign(target,…sources) es6新增方法可以浅拷贝
match : 提取,匹配
正则表达式
正则表达式是用于匹配字符串中字符组合的模式,在JavaScript中,正则表达式也是对象
-
可以进行文字的匹配、替换、提取
可以通过两种方式创建正则表达式
1.调用RegExp
对象的构造函数创建
var 变量名 = new RegExp (/表达式/)
2.通过字面量创建
var 变量名 = /表达式/
测试正则表达式test
test()正则对象方法,用于检测字符串是否符合该规则,该对象会返回true或false,其参数是测试字符串
regexObj.test(str)
-
regexObj
是写的正则表达式 -
str
要测试的文本
符号 | 说明 | |
---|---|---|
^ | 表示匹配行首的文本 | |
$ | 表示匹配行尾的文本 |
如果 ^和 $ 在一起,表示必须是精确匹配。
var rg = /abc/; // 正则表达式里面不需要加引号 不管是数字型还是字符串型
// /abc/ 只要包含有abc这个字符串返回的都是true
console.log(rg.test('abc'));
console.log(rg.test('abcd'));
console.log(rg.test('aabcd'));
console.log('---------------------------');
var reg = /^abc/;
console.log(reg.test('abc')); // true
console.log(reg.test('abcd')); // true
console.log(reg.test('aabcd')); // false
console.log('---------------------------');
var reg1 = /^abc$/; // 精确匹配 要求必须是 abc字符串才符合规范
console.log(reg1.test('abc')); // true
console.log(reg1.test('abcd')); // false
console.log(reg1.test('aabcd')); // false
console.log(reg1.test('abcabc')); // false
字符类
字符类表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内。
[] 方括号
表示有一系列字符可供选择,只要匹配其中一个就可以了
var rg = /[abc]/; // 只要包含有a 或者 包含有b 或者包含有c 都返回为true
console.log(rg.test('andy'));//true
console.log(rg.test('baby'));//true
console.log(rg.test('color'));//true
console.log(rg.test('red'));//false
var rg1 = /^[abc]$/; // 三选一 只有是a 或者是 b 或者是c 这三个字母才返回 true
console.log(rg1.test('aa'));//false
console.log(rg1.test('a'));//true
console.log(rg1.test('b'));//true
console.log(rg1.test('c'));//true
console.log(rg1.test('abc'));//true
----------------------------------------------------------------------------------
var reg = /^[a-z]$/ //26个英文字母任何一个字母返回 true - 表示的是a 到z 的范围
console.log(reg.test('a'));//true
console.log(reg.test('z'));//true
console.log(reg.test('A'));//false
-----------------------------------------------------------------------------------
//字符组合
var reg1 = /^[a-zA-Z0-9]$/; // 26个英文字母(大写和小写都可以)任何一个字母返回 true
------------------------------------------------------------------------------------
//取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
var reg2 = /^[^a-zA-Z0-9]$/;
console.log(reg2.test('a'));//false
console.log(reg2.test('B'));//false
console.log(reg2.test(8));//false
console.log(reg2.test('!'));//true
量词符
量词符用来设定某个模式出现的次数。
量词 | 说明 |
---|---|
* | 重复0次或更多次 |
+ | 重复1次或更多次 |
? | 重复0次或1次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
用户名表单验证
功能需求:
-
如果用户名输入合法, 则后面提示信息为: 用户名合法,并且颜色为绿色
-
如果用户名输入不合法, 则后面提示信息为: 用户名不符合规范, 并且颜色为红色
分析:
-
用户名只能为英文字母,数字,下划线或者短横线组成, 并且用户名长度为6~16位.
-
首先准备好这种正则表达式模式/$[a-zA-Z0-9-_]{6,16}^/
-
当表单失去焦点就开始验证.
-
如果符合正则规范, 则让后面的span标签添加 right类.
-
如果不符合正则规范, 则让后面的span标签添加 wrong类.
<input type="text" class="uname"> <span>请输入用户名</span>
<script>
// 量词是设定某个模式出现的次数
var reg = /^[a-zA-Z0-9_-]{6,16}$/; // 这个模式用户只能输入英文字母 数字 下划线 中划线
var uname = document.querySelector('.uname');
var span = document.querySelector('span');
uname.onblur = function() {
if (reg.test(this.value)) {
console.log('正确的');
span.className = 'right';
span.innerHTML = '用户名格式输入正确';
} else {
console.log('错误的');
span.className = 'wrong';
span.innerHTML = '用户名格式输入不正确';
}
}
</script>
3.3.4 括号总结
1.大括号 量词符. 里面表示重复次数
2.中括号 字符集合。匹配方括号中的任意字符.
3.小括号表示优先级
3.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] |
案例:验证座机号码
var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/;
var reg = /^\d{3,4}-\d{7,8}$/;
表单验证案例
//手机号验证:/^1[3|4|5|7|8][0-9]{9}$/;
//验证通过与不通过更换元素的类名与元素中的内容
if (reg.test(this.value)) {
// console.log('正确的');
this.nextElementSibling.className = 'success';
this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜您输入正确';
} else {
// console.log('不正确');
this.nextElementSibling.className = 'error';
this.nextElementSibling.innerHTML = '<i class="error_icon"></i>格式不正确,请从新输入 ';
}
//QQ号验证: /^[1-9]\d{4,}$/;
//昵称验证:/^[\u4e00-\u9fa5]{2,8}$/
//验证通过与不通过更换元素的类名与元素中的内容 ,将上一步的匹配代码进行封装,多次调用即可
function regexp(ele, reg) {
ele.onblur = function() {
if (reg.test(this.value)) {
// console.log('正确的');
this.nextElementSibling.className = 'success';
this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜您输入正确';
} else {
// console.log('不正确');
this.nextElementSibling.className = 'error';
this.nextElementSibling.innerHTML = '<i class="error_icon"></i> 格式不正确,请从新输入 ';
}
}
};
//密码验证:/^[a-zA-Z0-9_-]{6,16}$/
//再次输入密码只需匹配与上次输入的密码值 是否一致
3.5正则替换replace
replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。
var str = 'andy和red';
var newStr = str.replace('andy', 'baby');
console.log(newStr)//baby和red
//等同于 此处的andy可以写在正则表达式内
var newStr2 = str.replace(/andy/, 'baby');
console.log(newStr2)//baby和red
//全部替换
var str = 'abcabc'
var nStr = str.replace(/a/,'哈哈')
console.log(nStr) //哈哈bcabc
//全部替换g
var nStr = str.replace(/a/a,'哈哈')
console.log(nStr) //哈哈bc哈哈bc
//忽略大小写i
var str = 'aAbcAba';
var newStr = str.replace(/a/gi,'哈哈')//"哈哈哈哈bc哈哈b哈哈"
案例:过滤敏感词汇
<textarea name="" id="message"></textarea> <button>提交</button>
<div></div>
<script>
var text = document.querySelector('textarea');
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.onclick = function() {
div.innerHTML = text.value.replace(/激情|gay/g, '**');
}
</script>
ES6相关概念(★★)
什么是ES6
ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。
ES6新增语法
let(★★★)
ES6中新增了用于声明变量的关键字
let声明的变量只在所处于的块级有效
if (true) {
let a = 10;
}
console.log(a) // a is not defined
注意:使用let关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性。
不存在变量提升
console.log(a); // a is not defined
let a = 20;
暂时性死区
利用let声明的变量会绑定在这个块级作用域,不会受外界的影响
var tmp = 123;
if (true) {
tmp = 'abc';
let tmp;
}
经典面试题
var arr = [];
for (var i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();
arr[1]();
经典面试题图解:此题的关键点在于变量i是全局的,函数执行时输出的都是全局作用域下的i值。
let arr = [];
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();
arr[1]();
经典面试题图解:此题的关键点在于每次循环都会产生一个块级作用域,每个块级作用域中的变量都是不同的,函数执行时输出的是自己上一级(循环产生的块级作用域)作用域下的i值.
小结
-
let关键字就是用来声明变量的
-
使用let关键字声明的变量具有块级作用域
-
在一个大括号中 使用let关键字声明的变量才具有块级作用域 var关键字是不具备这个特点的
-
防止循环变量变成全局变量
-
使用let关键字声明的变量没有变量提升
-
使用let关键字声明的变量具有暂时性死区特性
const(★★★)
声明常量,常量就是值(内存地址)不能变化的量
具有块级作用域
if (true) {
const a = 10;
}
console.log(a) // a is not defined
声明常量时必须赋值
const PI; // Missing initializer in const declaration
常量赋值后,值不能修改
const PI = 3.14;
PI = 100; // Assignment to constant variable.
const ary = [100, 200];
ary[0] = 'a';
ary[1] = 'b';
console.log(ary); // ['a', 'b'];
ary = ['a', 'b']; // Assignment to constant variable.
小结
-
const声明的变量是一个常量
-
既然是常量不能重新进行赋值,如果是基本数据类型,不能更改值,如果是复杂数据类型,不能更改地址值
-
声明 const时候必须要给定值
let、const、var 的区别
-
使用 var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象
-
使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
-
使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值
var | let | const |
---|---|---|
函数级作用域 | 块级作用域 | 块级作用域 |
变量提升 | 不存在变量提升 | 不存在变量提升 |
值可更改 | 值可更改 | 值不可更改 |
解构赋值(★★★)
ES6中允许从数组中提取值,按照对应位置,对变量赋值,对象也可以实现解构
数组解构
let [a, b, c] = [1, 2, 3];
console.log(a)//1
console.log(b)//2
console.log(c)//3
//如果解构不成功,变量的值为undefined
对象解构
let person = { name: 'zhangsan', age: 20 };
let { name, age } = person;
console.log(name); // 'zhangsan'
console.log(age); // 20
let {name: myName, age: myAge} = person; // myName myAge 属于别名
console.log(myName); // 'zhangsan'
console.log(myAge); // 20
小结2
使用 … 作为延展符号时一般是要将一个数组做为实参来使用
伪数组本身就是个对象,这个对象的属性是数字构成的且包含一个length
let arrayLike = {
'0':'a',
'1':2,
'length':2
}
-
解构赋值就是把数据结构分解,然后给变量进行赋值
-
如果结构不成功,变量跟数值个数不匹配的时候,变量的值为undefined
-
数组解构用中括号包裹,多个变量用逗号隔开,对象解构用花括号包裹,多个变量用逗号隔开
-
利用解构赋值能够让我们方便的去取对象中的属性跟方法
箭头函数(★★★)
ES6中新增的定义函数的方式。
() => {} //():代表是函数; =>:必须要的符号,指向哪一个代码块;{}:函数体
const fn = () => {}//代表把一个函数赋值给fn
函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号
function sum(num1, num2) {
return num1 + num2;
}
//es6写法
const sum = (num1, num2) => num1 + num2;
如果形参只有一个,可以省略小括号
function fn (v) {
return v;
}
//es6写法
const fn = v => v;
箭头函数不绑定this关键字,箭头函数中的this,指向的是函数定义位置的上下文this
const obj = { name: '张三'}
function fn () {
console.log(this);//this 指向 是obj对象
return () => {
console.log(this);//this 指向 的是箭头函数定义的位置,那么这个箭头函数定义在fn里面,而这个fn指向是的obj对象,所以这个this也指向是obj对象
}
}
const resFn = fn.call(obj);
resFn();
小结
-
箭头函数中不绑定this,箭头函数中的this指向是它所定义的位置,可以简单理解成,定义箭头函数中的作用域的this指向谁,它就指向谁
-
箭头函数的优点在于解决了this执行环境所造成的一些问题。比如:解决了匿名函数this指向的问题(匿名函数的执行环境具有全局性),包括setTimeout和setInterval中使用this所造成的问题
面试题
var age = 100;
var obj = {
age: 20,
say: () => {
alert(this.age)
}
}
obj.say();//箭头函数this指向的是被声明的作用域里面,而对象没有作用域的,所以箭头函数虽然在对象中被定义,但是this指向的是全局作用域
剩余参数(★★)
剩余参数语法允许我们将一个不定数量的参数表示为一个数组,不定参数定义方式,这种方式很方便的去声明不知道参数情况下的一个函数
function sum (first,
剩余参数和解构配合使用
let students = ['wangwu', 'zhangsan', 'lisi'];
let [s1,
ES6 的内置对象扩展
Array 的扩展方法(★★)
扩展运算符(展开语法)
扩展运算符可以将数组或者对象转为用逗号分隔的参数序列
let ary = [1, 2, 3];
扩展运算符可以应用于合并数组
// 方法一
let ary1 = [1, 2, 3];
let ary2 = [3, 4, 5];
let ary3 = [
将类数组或可遍历对象转换为真正的数组
let oDivs = document.getElementsByTagName('div');
oDivs = [
构造函数方法:Array.from()
将伪数组或可遍历对象转换为真正的数组
//定义一个集合
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
//转成数组
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组
let arrayLike = {
"0": 1,
"1": 2,
"length": 2
}
let newAry = Array.from(arrayLike, item => item *2)//[2,4]
注意:如果是对象,那么属性需要写对应的索引
实例方法:find()
用于找出第一个符合条件的数组成员,如果没有找到返回undefined
let ary = [{
id: 1,
name: '张三'
}, {
id: 2,
name: '李四'
}];
let target = ary.find((item, index) => item.id == 2);//找数组里面符合条件的值,当数组中元素id等于2的查找出来,注意,只会匹配第一个
实例方法:findIndex()
用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1
let ary = [1, 5, 10, 15];
let index = ary.findIndex((value, index) => value > 9);
console.log(index); // 2
实例方法:includes()
判断某个数组是否包含给定的值,返回布尔值。
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
String 的扩展方法
模板字符串(★★★)
ES6新增的创建字符串的方式,使用反引号定义
let name = `zhangsan`;
模板字符串中可以解析变量
let name = '张三';
let sayHello = `hello,my name is ${name}`; // hello, my name is zhangsan
模板字符串中可以换行
let result = {
name: 'zhangsan',
age: 20,
sex: '男'
}
let html = ` <div>
<span>${result.name}</span>
<span>${result.age}</span>
<span>${result.sex}</span>
</div> `;
在模板字符串中可以调用函数
const sayHello = function () {
return '哈哈哈哈 追不到我吧 我就是这么强大';
};
let greet = `${sayHello()} 哈哈哈哈`;
console.log(greet); // 哈哈哈哈 追不到我吧 我就是这么强大 哈哈哈哈
实例方法:startsWith() 和 endsWith()
-
startsWith():表示参数字符串是否在原字符串的头部,返回布尔值
-
endsWith():表示参数字符串是否在原字符串的尾部,返回布尔值
let str = 'Hello world!';
str.startsWith('Hello') // true
str.endsWith('!') // true
实例方法:repeat()
repeat方法表示将原字符串重复n次,返回一个新字符串
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
Set 数据结构(★★)
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set本身是一个构造函数,用来生成 Set 数据结构
const s = new Set();
Set函数可以接受一个数组作为参数,用来初始化。
const set = new Set([1, 2, 3, 4, 4]);//{1, 2, 3, 4}
实例方法
-
add(value):添加某个值,返回 Set 结构本身
-
delete(value):删除某个值,返回一个布尔值,表示删除是否成功
-
has(value):返回一个布尔值,表示该值是否为 Set 的成员
-
clear():清除所有成员,没有返回值
const s = new Set();
s.add(1).add(2).add(3); // 向 set 结构中添加值
s.delete(2) // 删除 set 结构中的2值
s.has(1) // 表示 set 结构中是否有1这个值 返回布尔值
s.clear() // 清除 set 结构中的所有值
//注意:删除的是元素的值,不是代表的索引
遍历
Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。
s.forEach(value => console.log(value))