1.课程介绍
1.es是什么
2.新特性的优点
3.学习课程必备知识背景
2.相关名词介绍
3. let变量声明以及声明特性
3.1变量声明方式
//普通声明
let a;
//一次性声明多个变量
let a,b,c;
//声明并且初始化
let a = 100;
//一次性声明多个并且初始化
let a=2,b=1,c='i love you';
3.2不允许重复声明
//使用 var 进行声明时下述代码不会报错
var a = 1;
var a = 2;
//使用 let 进行声明时下述代码会报错
let a = 3;
let a = [];
3.3块级作用域
块的范围一般包括 if else while for 等
//es6中变量作用域的范围,除了全局作用域/函数作用域/eval作用域,还有块级作用域
{
var a = 6;
let b =7
}
//a可以正常打印
console.log(a)
//b会报错is not defined
console.log(b)
3.4不存在变量提升
//a会输出undefined,因为对变量的声明自动提升了
console.log(a);
//b会报错 cannot access before initialization,因为不能提升
console.log(b);
var a = 2;
let b = 3;
3.5不影响作用域链
let a = 2;
function fn(){
return a;
}
//可以通过作用域链获取到a并返回
console.log(fn());
4.let块级作用域经典案例实践
例如,现在想给每一个div设置背景颜色为粉色
<!DOCTYPE html>
<html lang="en">
<style>
.test{
border: 1px solid;
height: 50px;
width: 20px;
}
</style>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
</body>
<script>
var items = document.getElementsByClassName("test");
//当下面通过var进行声明的时候,功能无法正常起作用,而let可以
//是因为在绑定点击事件之后,i已经是3,而实际点击时候没有下标为3的元素
//而let块级作用域结束后,再次点击时会从0开始,即可获取正确下标
for(var i=0;i<items.length;i++){
items[i].onclick = function () {
items[i].style.background = 'pink';
}
}
</script>
</html>
5.const声明常量
5.1声明常量的格式,一般变量名称采用大写
const A = 1;
5.2必须赋初始值
//必须赋初始值,下面这种情况会报错
const A;
5.3常量的值不能修改
//常量的值不能修改,下面的赋值语句会报错
const A = 1;
A = 2;
5.4常量也是块级作用域
{
const A = 1;
}
//会报错
console.log(A)
5.5对数组或者对象里面的内容进行修改,不算对它的值进行操作,可以成功
const A = [1,2,3]
A.push(4)
console.log('[ A ] >', A)
6.变量的解构赋值
6.1变量的解构赋值
let arr = [1,2,3]
let [a,b,c] = arr
console.log('[ a ] >', a)
console.log('[ b ] >', b)
console.log('[ c ] >', c)
6.2对象的解构赋值
let student = {
name : 'ljk',
age : 10,
whatHeSay : 'i love sy'
}
let{name,age,whatHeSay} = student
console.log('[ name ] >', name)
console.log('[ age ] >', age)
console.log('[ whatHeSay ] >', whatHeSay)
7.模板字符串
7.1通过反引号来声明字符串类型变量
let a = `sdfsdfs`;
console.log('[ a ] >', a)
console.log('[ typeOfa ] >', typeof a)
7.2不用通过拼接来换行
let a = `<ul>
<li>a</li>
<li>a</li>
<li>a</li>
<li>a</li>
<li>a</li>
</ul>`;
console.log('[ a ] >', a)
7.3通过${}进行变量的拼接
let a = `123`
let b = `${a}456`
console.log('[ b ] >', b)
8.对象的简化写法
8.1对于变量以及方法,均可以简写
var name = "a"
var age = 10
//这是之前的写法
// let student = {
// name:name,
// age:age,
// speech:function(){
// return this.age
// }
// }
let student = {
name,
age,
speech(){
return this.age
}
}
console.log('[ student ] >', student)
console.log('[ student.speech ] >', student.speech())
9.箭头函数
9.1箭头函数书写方式
//正常写函数
let a = function(){
}
//去掉function关键字,后面加上箭头,就是箭头函数
let b = () => {
}
//调用方式和普通函数一样
b();
//当形参有且只有一个的时候,小括号可以省略
let add = (n) => {
return n + 1
}
//可以写成如下方式
let add = n => {
return n + 1
}
//当函数体仅有一行时,大括号可以省略,上述代码可以如下这样写,注意要去掉return关键字
let add = n => n + 1
9.2静态的this(始终是声明时所在作用域下的this)
let fn = function(){
console.log('[ name ] >', this.name)
}
let fnArr = () => {
console.log('[ name ] >', this.name)
}
window.name = 'window name'
const bean = {name:'beanName'}
//正常调用时,this均是window
fn();
fnArr();
console.log('[ -------- ] >')
//采用call时,普通函数的this是当前对象
fn.call(bean)
//而箭头函数的this还是window,它是静态的,始终是声明时所在作用域下的this
fnArr.call(bean)
9.3不能使用箭头函数定义构造方法
//普通的构造方法
let person = function(name,age){
this.name = name;
this.age = age;
}
//箭头函数的构造方法
let personArr = (name,age) => {
this.name = name;
this.age = age;
}
//能够进行调用
console.log('[ person ] >', new person("ljk",20))
//调用的时候会报错
console.log('[ personArr ] >', new personArr("sy",21))
9.4箭头函数不能使用arguments获取参数
//正常函数
let fn = function(){
console.log('[ arguments ] >', arguments)
}
//箭头函数
let fnArr = () => {
console.log('[ arguments ] >', arguments)
}
10.箭头函数的实际应用场景
需求1:点击之后2s方框变成粉色
//获取页面元素
let box = document.getElementById("box");
box.addEventListener("click",function(){
setTimeout(function(){
//普通函数写法,这里的this是window对象,所以无法实现功能
console.log('[ this ] >', this)
this.style.backgroundColor = 'pink';
}, 2000);
})
box.addEventListener("click",function(){
setTimeout(() => {
//箭头函数写法,这里的this是声明时所在作用域的对象,可以实现功能
console.log('[ this ] >', this)
this.style.backgroundColor = 'pink';
}, 2000);
})
需求2:从数组中返回偶数元素
const Arr = [1,3,5,7,8,10];
//正常书写模式
let even = Arr.filter(function (item){
if(item % 2 === 0){
return true;
}else{
return false;
}
})
console.log('[ even ] >', even)
//箭头函数书写模式,比较简洁,因为箭头函数省略大括号时,箭头后面的值就是默认的返回值
let evenArr = Arr.filter(item => item % 2 === 0)
console.log('[ evenArr ] >', evenArr)
##10.3箭头函数的适用场景
适用于:
1.与this无关的回调
2.定时器
3.数组的方法回调
不适用于:
1.与this有关的回调
2.事件回调
3.对象的方法
11.给函数参数赋初始值
11.1赋初始值的写法
//函数正常来说应该这么写
function a (a,b,c){
return a+b+c;
}
//结果:[ a(1,2,3) ] > 6
console.log('[ a(1,2,3) ] >', a(1,2,3))
//如果部分变量没有传参,就是这样的
//1+2+NaN = NaN 结果: [ a(1,2,3) ] > NaN
console.log('[ a(1,2,3) ] >', a(1,2))
//赋初始值的写法是这样的
function a2 (a,b,c = 10){
return a+b+c;
}
//结果[ a2(1,2,3) ] > 13
console.log('[ a2(1,2,3) ] >', a2(1,2))
11.2可以与解构赋值一起使用
//当传参为对象的时候,一般情况下是这么写的
let person = {
age:20,
name:"ljk"
}
function a (person){
console.log('[ person.age ] >', person.age);
console.log('[ person.name ] >', person.name);
}
a(person);
//这时候会发现person.age 与 person.name都在重复书写,耦合性比较高
//可以采取就解构赋值的方法进行优化代码,同时也可以赋初始值
let person2 = {
age:20
}
function a2 ({age,name = "sy"}){
console.log('[ person.age ] >', age);
console.log('[ person.name ] >', name);
}
a2(person2);
12.rest参数
//之前采用的argument参数
function a(){
console.log('[ arguments ] >', arguments)
}
a(1,2,3,4,5)
//rest参数的使用,注意...args必须放在最后,否则会报错
function b(a,b,...args){
console.log('[ a ] >', a)
console.log('[ b ] >', b)
console.log('[ args ] >', args)
}
b(1,2,3,5,6,7,8)
13.扩展运算符
let a1 = [1,2]
function fn(){
console.log('[ arguments ] >', arguments)
}
//调用方法时,正常传参是一个数组
fn(a1)
//采用扩展运算符,会把数组中的每一个元素拆分出来
fn(...a1)
14.扩展运算符的应用
14.1用于数组的拼接
let a = [1,2]
let b = [3,4]
console.log('[ [...a,...b] ] >', [...a,...b])
14.2用于数组的克隆
let a = [1,2]
let b = [...a]
console.log('[ b ] >', b)
15.Symbol数据类型
//创建方式一,函数式创建
let a = Symbol();
//结果:[ a ] > Symbol()
console.log('[ a ] >', a)
//结果:[ typeof a ] > symbol
console.log('[ typeof a ] >', typeof a)
//在创建时还可以添加参数,只作为提示字符的作用
let a2 = Symbol("a");
let a3 = Symbol("a");
//注意,通过函数方式创建的symbol变量值是不一样的
//结果: [ a2 === a3 ] > false
console.log('[ a2 === a3 ] >', a2 === a3)
//创建方式二,Symbol.for创建
let a4 = Symbol.for("a");
let a5 = Symbol.for("a");
//通过这种方式可以创建同一个值的symbol
//结果: [ a4 === a5 ] > true
console.log('[ a4 === a5 ] >', a4 === a5)
//注意。symbol类型不能进行任何运算
let a = Symbol();
a += 1;
15.2巧记js中的7中数据类型
// u so nb 你很牛逼
undefined
string symbol
object
null number
boolean
15.3 Symbol数据类型扩展知识
15.3.1 Symbol的作用
用来表示一个独一无二的值
15.3.2 为什么需要Symbol?
为了避免第三方框架的同名属性被覆盖
在企业开发中如果需要对一些第三方的插件、框架进行自定义的时候
可能会因为添加了同名的属性或者方法, 将框架中原有的属性或者方法覆盖掉
为了避免这种情况的发生, 框架的作者或者我们就可以使用Symbol作为属性或者方法的名称