一.使用let关键字申明变量
1.let申明的变量才具有块级作用域,而var并不具有这个功能
<script>
if(true){
var a=200
let num =100
}
console.log(a);
console.log(num);
</script>
同样在for循环中,可以看到效果:
我们要防止使用var,防止循环变量变成全局变量。
<script>
for (var index = 0; index < 2; index++) {
}
console.log(index);// 2
</script>
<script>
for (let index = 0; index < 2; index++) {
}
console.log(index);// index is not defined
</script>
2.let不存在变量提升,而var会
console.log(a);// Cannot access 'a' before initialization
let a=10
console.log(a);//undefined 此时变量提升了,但是并没有获取到值
var a=10
let有暂时性死区
<script
var num=30
if(true){
//在此区域申明用let申明的变量具有块级作用域,它并不会访问外部的变量
console.log(num);//Cannot access 'num' before initialization
let num=20
}
</script>
接下来附加两道题:
<script>
var arr = []
for (var index = 0; index < 2; index++) {
arr[index] = function () {
console.log(index);
}
}
arr[0]()//2
arr[1]()//2
</script>
<script>
let arr = []
for (let index = 0; index < 2; index++) {
arr[index] = function () {
console.log(index);
}
}
arr[0]()//0
arr[1]()//1
</script>
使用const申明的常量也具有块级作用域
<script>
if (true) {
const a = 10
console.log(a);//10
if (true) {
const a = 20
console.log(a);//20
}
}
console.log(a); //a is not defined
</script>
使用const申明的变量必须赋初始值
const申明常量,常量就是值(内存地址)不能变化的值
const PI=3.14
PI=100 //Assignment to constant variable.
对于复杂数据类型,比如说对象,它内部的值是可以更改的,但是你对他它重新赋值,就是不可以的,也就是说常量所对应的内存地址是不可更改的,来看下列代码:
const arr=[100,200]
arr[0]=123
console.log(arr);//[123,200]
arr=[1,2] //更改常量所对应的内存地址,不可以
console.log(arr)// Assignment to constant variable.
总结:var ,let 及 const的区别
a.使用var申明的变量,其作用域就是该语句所在的函数内,且存在变量提升现象;
b.使用let申明的变量,其作用域就是该语句所在的代码快内,不存在变量提升现象;
c.使用const申明的是常量,在后面出现的代码中不能再修改该常量出现的值。
二、解构赋值
1.数组解构:允许我们按照一一对应关系从数组中取值,然后将值赋给常量。解构不成功的话,会返回underfined.
<script>
let arr=[1,2,3]
let [a,b,c,d,e]=arr
console.log(a);//1
console.log(b);//2
console.log(c);//3
console.log(d);//undefined
console.log(e);//undefined
</script>
2.对象解构
a.第一种写法:
let person={name:'阿航',age:'18',sex:'男'}
let {name,age,sex}=person
console.log(name);
console.log(age);
console.log(sex);
b.第二种写法:
let person={name:'阿航',age:'18',sex:'男'}
let {name:myName}=person //冒号左边的name用于属性匹配,myName才是真正的变量
console.log(myName);//阿航
三、箭头函数:用来简述函数定义的语法
const fn = () => {
console.log(123);
}
fn()
箭头函数中,如果函数只有一句代码,并且代码的执行结果就是函数的返回值,那么大括号可以省略不写。
const sum=(a,b)=>a+b
const res=sum(10,20)
console.log(res);//30
箭头函数中,如果形参只有一个,形参外侧的小括号也是可以省略的。
const fn = n => {
console.log(123);
}
fn()
箭头函数不绑定this,箭头函数中的this,指的是函数定义位置的上下文this.
function fn() {
console.log(this); //{name: '李诞'}
return () => {
console.log(this); //{name: '李诞'}
}
}
let obj = {
name: '李诞'
}
const resFn = fn.call(obj)
resFn()
附加一道箭头函数的题目:
var obj={
age:20,
say:()=>{
console.log(this.age);//指向window下面的age,并无此属性,打印undefined
}
}
obj.say()
//对象并没有自己的作用域,say方法其实是定义在了全局作用域window下(本题关键)
把这道题改造一下:
var age = 50
var obj = {
age: 20,
say: () => {
console.log(this.age);//50 输出了window的age属性
}
}
obj.say()
四、剩余参数:允许我们将一个不定数量的参数表示为一个数组。
<script>
const sum = (...args) => {
let total = 0
args.forEach(item => total += item)
return total
}
sum(10, 20)
sum(10, 20, 30)
console.log(sum(10, 20));//30
console.log(sum(10, 20, 30));//60
</script>
a.剩余参数和解构赋值配合使用
let students=['李诞','徐志胜','何广智']
let [s1,...s2]=students
console.log(s1);//李诞
console.log(s2); //['徐志胜', '何广智']
五、扩展运算符(展开语法):可以将数组或对象转为用逗号分割的参数序列。
<script>
let arr=[1,2,3]
console.log(...arr);//1 2 3
</script>
扩展运算符用途:a.可以用于合并数组;
let arr1=[1,2,3]
let arr2=[4,5,6]
let arr3=[...arr1,...arr2]
console.log(arr3);//[1, 2, 3, 4, 5, 6]
上述代码的另一种写法:
let arr1=[1,2,3]
let arr2=[4,5,6]
arr1.push(...arr2)
console.log(arr1);//[1, 2, 3, 4, 5, 6]
b.将伪数组或者可遍历对象转换成真正的数组,就可以用到数组的方法了。
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<script>
let divs = document.getElementsByTagName('div')
console.log(divs); //HTMLCollection(5) [div, div, div, div, div]
let ary = [...divs] //将伪数组转换成真正的数组
console.log(ary); //[div, div, div, div, div]
ary.push('a')
console.log(ary);// [div, div, div, div, div, 'a']
</script>
六、内置对象扩展
(1)Array的扩展方法
1.利用Array的扩展方法Array.from()也可以将伪数组转换成真正的数组:
let obj = {
'0': '李诞',
'1': '池子',
'2': '王建国',
'length': 3
}
let transObj = Array.from(obj)
console.log(transObj); //['李诞', '池子', '王建国']
Array.from()方法还可以接收第二个参数,类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
let obj = {
'0': '1',
'1': '2',
'2': '3',
'length': 3
}
let transObj = Array.from(obj,item=>item*2)
console.log(transObj); //[2, 4, 6]
2.实例方法:find() 找到符合条件的第一个数组成员,没有找到则返回undefined。
<script>
let arr1=[
{
id:1,
name:'张雨绮'
},
{
id:2,
name:'虞书欣'
}
]
let arr2=arr1.find(item=>item.id==2)
let arr3=arr1.find(item=>item.id==3)
console.log(arr2);//{id: 2, name: '虞书欣'}
console.log(arr3);//undefined
</script>
3.实例方法:findIndex() 找到符合条件的第一个数组成员的索引位置,没有找到则返回-1。
let arr=[1,3,10,15]
let index1=arr.findIndex(item=>item>9)
let index2=arr.findIndex(item=>item>20)
console.log(index1);//2
console.log(index2);//-1
4.实例方法includes(),表示某个数组是否包含给定的值,返回布尔值。
[1,2,3].includes(2)//true
[1,2,3].includes(4)//false
(2)String的扩展方法
1.模板字符串
<script>
let name='李明浩'
let logName=`我的名字是${name}`
console.log(logName);//我的名字是李明浩
</script>
模板字符串可以换行显示:
let res = {
name: '徐艺',
age: '20',
sex: '男'
}
let html = `
<div>
<span>${res.name}</span>
<span>${res.age}</span>
<span>${res.sex}</span>
</div>
`
console.log(html);
在模板字符串中可以调用函数:
const fn = () => {
return '我是模板字符串fn'
}
let html = `我是模板字符串,${fn()}`
console.log(html);//我是模板字符串,我是模板字符串fn
2.两种实例方法: startsWith() 和 endsWith()
startsWith():表示参数字符串是否在原字符串的头部,返回布尔值;
endsWith():表示参数字符串是否在原字符串的尾部,返回布尔值;
let str = 'Hello year 2022'
let res1 = str.startsWith('Hello')
console.log(res1);//true
let res2=str.endsWith('2023')
console.log(res2);//false
3.实例方法:repeat()
repeat()方法表示将原字符串重复n次,得到一个新字符串。
<script>
console.log('y'.repeat(5));//yyyyy
</script>
4.Set数据结构,它类似于数组,但是成员的值都是唯一的,没有重复的值。
<script>
//Set本身是一个构造函数,用来生成Set数据结构
let res1=new Set()
console.log(res1.size);//0
let res2=new Set(['a','b'])//可以接收一个数组作为Set的参数
console.log(res2.size);//2
</script>
利用new Set()还可以做数组去重:
//利用new Set()还可以做数组去重
let arr = new Set(['a', 'a', 'b', 'b'])
console.log(arr.size);//2
const res3 = [...arr]
console.log(res3);//['a', 'b']
Set实例的方法:
(1)add(value):添加某个值,返回Set结构本身;
(2)delete(value):删除某个值,返回一个布尔值,表示是否删除成功;
(3)has(value):返回一个布尔值,表示该值是否是Set的成员;
(4)clear():清除所有成员,没有返回值。
const s1 = new Set()
//向Set结构中添加数值,使用add方法
let res1 = s1.add('a').add('b')
console.log(res1.size); //2
//从Set结构中删除数值,使用delete方法,还返回一个布尔值,表示是否删除成功
let res2 = s1.delete('a')
console.log(s1.size); //1
console.log(res2); //true
//判断某一个数值是否是Set结构中的成员,使用has方法
let res3 = s1.has('b')
console.log(res3); //true
//清空Set结构中的所有值,使用clear方法
let res4 = s1.clear()
console.log(s1.size);//0 表示没有成员
也可以遍历Set数据结构,从中取值:
let arr = new Set(['a', 'b', 'c'])
arr.forEach(item => {
console.log(item); // a b c
})