2.第三阶段课程简介
修心。为后面阶段做储备 。vue、react、小程序
本阶段主要作用:深刻理解前后端交互 。
Ecmascript6
Node:是后端语言。
Express
Mysql
项目:数据
学习Node+Mysql+Express :你会设计一些基本的数据接口,供自己使用即可。
Webpack:小工具,打包的。
3.ECMASCript简介
ECMAScript 6.0(以下简称 ES6)泛指 JavaScript 语言的下一代标准。
现在浏览器及类似浏览器对es6支持非常友好 。
3.1 ES6与ES5
ES5: es1、2、3 、5
es4: 这个标准太激进 。2015年 es6。 Ecmascript 2015.每年6月份都会发布最新的。es7/8/9/10
3.2 ES与JS的关系
js是es的体现 。
3.3 总结
js已经触及到后端 。
4.严格模式(了解)
ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";
4.1 为什么有严格模式
- 消除 JavaScript 语法的一些不合理、不严谨之处,减少一些怪异行为
- 消除代码运行的一些不安全之处,保证代码运行的安全
- 提高编译器效率,增加运行速度
- 为未来新版本(es6)的 JavaScript 做好铺垫
4.2 严格模式的特点
-
声明定义变量必须用 var
-
禁止函数中的 this 指向Window
-
eval拥有独立作用域
eval函数示例:
// eval( 'var b = 3 + 5' )
// eval( 'var a = 3' )
// console.log(a);
// console.log(b);
var a = 1
eval( 'var a = 3;console.log(a)' )
console.log(a)
二、let和const命令
ES6 新增了let
命令,用来声明变量。
ES6新增了const
命令用来声明一个只读的常量。
1.let命令
1.1 基础用法
代码案例:
let variable = value
// console.log( username );//username 未定义 Cannot access 'username' before initialization
let username = 'swk'
console.log( username ); //更加严谨 ,没有变量提升 。
1.2 let命令特点
1.2.1 不存在变量提升与暂时性死区
代码案例:
let a = 1
let b = 2
function fn1(){
console.log( a ); //作用域链 1
console.log( b );//Cannot access 'b' before initialization 暂时性死区
let b = 3 ;//
}
fn1()
1.2.2 不能重复声明
代码案例:
let c = 123
let c = 456 // SyntaxError: Identifier 'c' has already been declared
1.2.3 块级作用域
代码案例:
{
let a = 111
let b = 333
{
{
let a = 222
console.log( a );
console.log( b );//报错 Cannot access 'b' before initialization
let b = 4444
}
}
}
1.2.4 let和循环
代码案例:
<button>1</button><button>2</button><button>3</button>
<script>
let btns = document.getElementsByTagName('button')
for( let i=0;i<btns.length ;i++ ){
btns[i].onclick = function(){
alert( i )
}
}
</script>
2.const命令
2.1 基础用法
代码案例:
//const 声明常量的。
//什么是常量?不能改变的( js中指的是内存地址不能改变 )。声明常量的时候,就必须赋值。
// 推荐常量名称用大写。
// PI : 3.1415926 Math.PI 身份证号 域名 端口号。 地址。
// const ADDRESS = '北京朝阳王四营乡道口村京忱润业'
// console.log( ADDRESS );
2.2 const特点及建议
代码案例:
// const a // Missing initializer in const declaration 未初始化值
// const a = 123
// a = 2345 // Assignment to constant variable. 一旦定义常量不能修改
const person = {
username:'zbj',
job:'背翠兰,吃,睡'
}
person.job = '拍马屁'
person = {} //Assignment to constant variable. 一旦定义常量不能修改 内存地址变了
3.总结
以后用var的地方都用let
值后期会不会变,如果不会改变用const
三、变量的解构赋值
1.概念及意义
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
数据结构 。
解构赋值:两层含义,分析数据的结构( 有序的【数组】、无序的【对象】 ),然后给变量赋值
2.数组解构
语法:let [ var1,var2,var3,var4,… ] = [ value1,value2,value3,… ]
2.1 完全解构
代码案例:
let [ a,b,c ] = [11,22,33]
console.log( a,b,c );//11,22,33
2.2 不完全解构
代码案例:
let [ a,b ] = [ 11,22,33 ]
console.log( a,b );//11,22
2.3 解构失败
代码案例:
代表变量没有赋值。undefined
let [ a,b,c ] = [ 11 ]
console.log( a,b,c );//11, undefined ,undefined
2.4 解构默认值
代码案例:
// 在左边设置默认值 , 必须未赋值或者赋值一个undefined,默认值才生效
let [ a,b=333,c=444 ] = [ 11,undefined,null ]
console.log( a,b,c );//b 和 c的默认值会生效。b=333 c=null
2.5 数组解构应用(数据交换)
代码案例:
let a1 = 123;
let a2 = 456;
[ a1,a2 ] = [ a2,a1 ];
console.log( a1,a2 );
3.对象解构
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,而对象的属性没有次序。
语法:
let { key2:variable2,key1:variable1,... } = { key1:value1,key2:value2,...}
let { key2,key1,... } = { key1:value1,key2:value2,...}
3.1 完全解构
代码案例:
// let { job:ujob ,uesrname:uname} = { uesrname:'swk',job:'斩妖除魔' }
// console.log( uname,ujob );
// let { job,uesrname } = { uesrname:'swk',job:'斩妖除魔' }
// console.log( job ,uesrname );
3.2 不完全解构
代码案例:
let { job } = { uesrname:'swk',job:'斩妖除魔' }
3.3 解构默认值
代码案例:
let { age = 20,a=333 } = { uesrname:'swk',job:'斩妖除魔',a:null }
console.log( age ,a);//20 null
3.4 解构失败
代码案例:
// let { age } = { uesrname:'swk',job:'斩妖除魔' }
// console.log( age );//undefined
3.5 使用场景
只要从对象中取值,如果大家觉得之前的点语法或中括号的写法比较麻烦,那么就可以使用解构赋值。
代码案例:
let oDiv = document.getElementById('div1')
oDiv.onclick = function( ev ){
//var ev = ev || window.event
// console.log( ev );
let { clientX,clientY } = ev || window.event
console.log( clientX,clientY );
}
3.6嵌套解构
let { list:[a] } = {
"msg": "操作成功",
"code": 200,
"list": [
{
"id": 1,
"title": "轮播图1",
"img": "/uploads/banner/18533110-4062-11eb-a164-a188131b487c.jpg",
"status": 1
},
{
"id": 2,
"title": "轮播图2",
"img": "/uploads/banner/26ccc9e0-4062-11eb-a164-a188131b487c.jpg",
"status": 1
}
]
}
console.log( a );
四、模板字符串
定义字符串。 ``
作用:解决之前的拼接问题。不能换行的问题。 模板字符串中可以执行js表达式 ${}
1.基础用法
代码案例:
//定义字符串
let str1 = `优就业`
let str2 = ` " 优就业 " 'IT培训' `
let person = {
username:'swk',
job:'斩妖除魔'
}
//我的法号:孙司空,我的职业:xxx
//1. 基本用法 : 解析变量表达式
let str = `我的法号:${ person.username },我的职业:${ person.job }`
2. 表达式执行
console.log( ` ${ 1+1 } ` );
function fn(){
return 'hello'
}
console.log( ` ${ fn() } ` );
2.优点
解决之前的拼接问题。不能换行的问题。 模板字符串中可以执行js表达式 ${}
<div id="result">
</div>
<script>
let { title,addTime,author } = {
title:'1234',
addTime :'2020-1',
author:'小U'
}
let str = `
<h2>${ title }</h2>
<p>
<span>发布时间:${ addTime }</span> <span>作者:${ author }</span>
</p>
`
console.log( str );
result.innerHTML = str;
</script>
五、对象扩展
万事万物皆对象,构造函数,__proto__
, prototype, 引用类型
创建对象:字面量 {} , new :Object
获取对象中的值:解构赋值、点语法、中括号的语法[ ]
1.对象属性简写
代码案例:
let username = 'swk'
let age = 20
let person = {
username,
age
}
console.log( person );
2.对象方法简写
代码案例:
//this的指向和function声明的函数this指向是一致的。
let obj = {
fn1:function(){
console.log('fn1',this)
},
fn2(){
console.log('fn2',this);
}
}
// obj.fn1()//obj
// obj.fn2()//obj
//call apply 事件函数...
obj.fn1.call( document )
obj.fn2.call( document )
3.对象属性表达式 []
代码案例:
表达式:变量,字符串拼接
// let person = {
// username:'swk',
// age:20
// }
// for(let attr in person){
// console.log( person[attr] )
// }
let hello = 'year'
let person1 = {
username:'zbj',
hello:'1234',
[hello]:2020,
[ 'a'+'b' ]:'我是ab属性'
}
// console.log( person1 );
console.log( person1.hello );//'1234'
console.log( person1[hello] );//2020
console.log( person1['year'] );//2020
4.新增方法
- Object.keys() : 获取对象上的所有的key【属性】, 可遍历的属性 以数组形式返回
- Object.values():获取对象上的所有的key对应的value【属性值】 可遍历的属性
用字面量形式创建的对象,默认所有的属性是可迭代的。
六、函数扩展
1.箭头函数基础用法
-
没有参数
-
一个参数
-
多个参数
-
有返回值
本意:写法简洁。经常应用于回调函数中。
已知A函数,B函数 把B函数传递到A函数中。那么B函数就是A的回调函数。那么B可以使用箭头函数。
代码案例:
/*
()=>{}
this:它的this取决于上层环境 。
*/
// - 没有参数
// let fn1 = ()=>{
// console.log( 1234 )
// }
// fn1()
// - 一个参数,如果只有一个参数,小括号可以省略
// let fn2 = ( num1 )=>{
// console.log( num1 );
// }
// fn2( 123 )
// let fn2 = num1 =>{
// console.log( num1 );
// }
// fn2( 123456 )
// - 多个参数 用逗号分割,小括号不能省略
// let fn3 = ( a,b )=>{
// console.log( a,b )
// }
// fn3( 11,22 )
// - 有返回值
// let fn4 = ()=>{
// return 1234
// }
//有返回值,且函数内只有一行代码,需要省略花括号并且也省略return
// let fn5 = ()=> 111
// console.log( fn5() )
//返回对象的问题,把对象用一个小括号包起来,提升优先级
let fn6 = ()=> ({
username:'swk'
})
console.log( fn6() )
2.箭头函数中this问题
补充:只有script全局和函数内才能称为环境
// 箭头函数它的this取决于上层环境的this是什么 。
// 当箭头函数声明以后,那么箭头函数中的this就永远确定了。
// call apply 事件都不会改变箭头函数的this指向 。
// let fn1 = ()=>{
// console.log( this )
// }
// fn1()//window
// let fn2 = ()=>{
// console.log( this )
// }
// fn2.call(document)//window
function Person(){
let fn = ()=>{
console.log(this)
}
fn()
}
Person()//window window.Person()
Person.call( document )//document
new Person()// person的实例对象
3.箭头函数的使用场景
经常应用于回调函数中,并且可以很方便地获取到具体业务的this。
let obj = {
a:123,
b:234,
cc:10000,
salarys:[ 20000,30000,4000 ],
fn1(){
//console.log(this);//obj
//console.log( this.salarys )
this.salarys.forEach( (item)=>{
// console.log( item )
console.log( this.cc )
} )
},
fn2:()=>{
console.log(this)//
}
}
obj.fn1()
// obj.fn2()//this=> window
4.函数参数默认值
// function ajax( url,method ){
// // console.log( url,method );
// if( typeof method == 'undefined' ){
// method = 'get'
// }
// console.log( method );
// }
// ajax()
//es6的默认值,更形象和简洁。 有默认的参数写后面
function ajax2( url,method='get' ){
console.log( method )
console.log( url )
}
// ajax2( 11,'get' )
ajax2( 'post' )
5. …运算符
5.1 扩展运算符(spread)
作用:展开对象或展开数组
代码案例:
//let arr = [11,22,33]
//spread: 展开数组或对象
// console.log( arr )
// console.log( ...arr ) //11,22,33
// console.log( 111,222,333 ) //111,222,333
//作用1:把数组传递给一个函数
// function fn( a,b,c ){
// console.log( a + b + c );
// }
// let arr = [10,20,30]
// fn( ...arr )//60
应用:
作用2:数组/对象的合并
let arr1 = [10,20]
let arr2 = [30,40]
let arr = [ ...arr1,...arr2 ]
console.log( arr );
//作用3:数组/对象的浅拷贝 如果你数组或对象中只有基本类型的数据,可以放心使用。
// let obj1 = { a:12,b:13,c:24 }
// let obj2 = obj1 //不算浅拷贝
let obj11 = { a:12,b:13,c:24,d:[11,22,33] }
let obj22 = { ...obj11 }
obj22.a = 11122
obj22.d.push(444)
console.log( obj11 );//不会改变 d:[11,22,33,r444]
console.log( obj22 );//a:11122 d:[11,22,33,r444]
5.2 rest参数
代码案例:
//在函数的形参中使用。作用:获取剩余参数 必须定义在形参的最后面。
//语法1:
// function fn( ...a ){ //获取了所有参数
// }
// function fn(aa,bb,cc, ...a ){ //获取剩余参数
// }
// function fn1(...arg){
// console.log( arg )//数组
// }
// fn1( 100,200,300 )
// function fn1(a,b,c,...arg){
// console.log( arg )//数组
// console.log( a,b,c );
// }
// fn1( 100,200,300,400,500 )
//rest参数的好处:我们就不需要使用arguments
//伪数组,类数组
// function fn1(){
// console.log( arguments )
// }
// fn1( 100,200,300,400,500 )
//箭头函数没有arguments对象,用的就是rest参数
let fn1 = ( ...arg1 )=>{
// console.log( arguments );未定义
console.log( arg1 );
}
fn1( 10,20 )
5.3补充:浅拷贝
操作的数组和对象这种数据结构 。
只是拷贝了一层这才是属于浅拷贝 。数组和对象可能有n多层。
let obj = { a:1,b:2 }
let obj2 = obj //拷贝的地址
七、知识点补充
1.Object方法扩展
1.1 Object.create()方法 了解
以指定对象为原型创建新的对象,为新的对象指定新的属性, 并对属性进行描述
语法:Object.create(prototype, descriptors)
value : 指定值
writable : 标识当前属性值是否是可修改的, 默认为false
configurable: 标识当前属性是否可以被删除 默认为false
enumerable: 标识当前属性是否能用for in 枚举 默认为false
代码案例:
let obj1 = {
username:'swk'
}
//age job
let newObj = Object.create( obj1,{
age:{
value:20,
enumerable:true,//可遍历
},
job:{
value:'西天取经',
enumerable:true,//可遍历
writable:true,//可修改
configurable:true,//可删除
}
} )
// console.log( newObj );
// console.log( newObj.username );
// console.log( newObj.age );
// newObj.job = '斩妖除魔'
delete newObj.job
console.log( newObj );
// for(let attr in newObj){
// console.log( attr )
// }
1.2 Object.defineProperties() 了解
为指定对象定义扩展多个属性
语法:Object.defineProperties(obj, props)
参数说明:
obj:在其上定义或修改属性的对象
props:
get :用来获取当前属性值得回调函数
set :修改当前属性值得触发的回调函数,并且实参即为修改后的值
代码案例:
1.3 Object.assign()
该方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)
语法:Object.assign(target,...source)
参数说明:
target:目标对象
source:源对象
代码案例:
2.Array方法扩展
1.Array.of()
语法:Array.of(element0,element1,...)
参数说明:
element0 要转换为数组的元素
...
代码案例:
2.Array.from()
语法:Array.from(arrayLike)
参数说明:
arrayLike:想要转换成数组的伪数组对象或可迭代对象
代码案例: