变量
var存在的问题:
- 可以重复声明
- 无法限制修改
- 没有块级作用域
let的优势
- 同一个块级作用域内不能重复声明
- 可以修改
- 有块级作用域
const优势
- 同一个块级作用域内不能重复声明
- 不可以修改
- 有块级作用域
函数
普通函数
function(){
//函数体
}
箭头函数
() => {
//函数体
}
1. 如果只有一个参数,()可以省略
2. 如果只有一个return语句,{}可以省略
let show=()=>{
alert("abc")
}
// show();
let show1= a => {
alert(a)
}
show1(777)
let arr=[12,5,8,99,14,26]
arr.sort((a,b) => {
return a-b
})
函数参数
参数扩展/展开
- 收集剩余的参数(Rest Parameter剩余参数必须是最后一个)
function show(a, b,...args,c){
alert(a)
alert(b)
alert(args)//3,5,7
alert(c)//报错,Rest Parameter剩余参数必须是最后一个
}
show(1,2,3,5,7)
- 展开数组:展开后的效果和直接把数组内容写在这儿一样
let arr=[1,2,3]
let arr1=[56,5,4]
let arr2=[...arr,...arr1]//arr+arr1
function show(a,b,c){
alert(a)
alert(b)
alert(c)
}
show(...arr)
let arr=[1,2,3]
let a=...arr//报错
function show(...args){
fn(...args)
}
function fn(a,b){
alert(a+b)
}
show(1,2,3,5)
默认参数
- 没有参数就用默认参数,有就用自身的实参
function show1(a,b=5,c=6){
alert(a+b+c)
}
show1(15)
show1(15,undefined,7)//只有中间参数为默认参数
解析赋值(结构赋值)
- 左右两边结构必须一样
- 右边必须是个东西
- 声明和赋值不能分开(必须在一句话里完成)
let [a,b,x]=[1,2,3]
let {c,d,y}={c:4,d:5,y:6}
let [json,arr,num,str]=[{a:12,b:5},[12,5,8],8,'an']
let [a,b]={a:12,b:15} //报错。左右两边结构必须一样
let {a,b}={5,7} //报错,右边不是一个合法的东西
数组
map (映射:一个对一个)
[112,58,6,990]
[及格,不及格,不及格,及格]
let arr=[12,5,8]
// let res=arr.map(function(item){
// return 2*item
// })
//es6简化版
let res=arr.map(item => item*2)
alert(res)
//数据映射
let score=[50,66,70,49,85]
let res=score.map(item => item>=60?'及格':'不及格')
console.log(score,res)
reduce
- 算总数,算平均数
let res1=score.reduce(function(tmp,item,index){
//tmp为上一次结果
//item为当前数字
//index为下标(迭代次数)
console.log(tmp,item,index)
if(index!=this.length-1){
return tmp+item
} else{
return (tmp+item)/arr.length
}
})
filter 过滤器
let res2=score.filter(item=>{
// if(item%4==0){
// return true
// }else{
// return false
// }
return item%4==0
})
forEach 循环(迭代)
let res3=score.forEach((item,index)=>{
return item//undefined,没有返回值
})
字符串
1. 多了两个新方法
- startWith
let str="https://www.baidu.com"
if(str.startsWith("http://")){
alert("普通网址")
}else if(str.startsWith("https://")){
alert("加密网址")
}else if(str.startsWith("git://")){
alert("git地址")
}else{
alert("其他")
}
- endWith
应用:- 通过文件扩展名判断文件类型
- 通过后缀名判断邮箱类型
2. 字符串模板(可以折行)------> ( ` )
- 把东西塞到字符串里面 ${字符串变量}
- 可以折行
let str1='a'
let str2="b"
//数据中使用较多
let str3=`a${str2}`//ab
let str4=`<div>
<h1>${title}</h1>
</div>`
面向对象
- class关键字、构造器和类分开了
- class里面直接加方法
// function User(name,pass){
// this.name=name
// this.pass=pass
// }
// User.prototype.showName=function(){
// alert(this.name)
// }
// User.prototype.showPass=function(){
// alert(this.pass)
// }
class User{
constructor(name,pass){
this.pass=pass
this.name=name
}
showName(){
alert(this.name)
}
showPass(){
alert(this.pass)
}
}
var user=new User('yan',1234)
user.showName()
继承
原始写法
function User(name,pass){
this.name=name
this.pass=pass
}
User.prototype.showName=function(){
alert(this.name)
}
User.prototype.showPass=function(){
alert(this.pass)
}
function VipUser(name,pass,level){
User.call(this,name,pass)
this.level=level
}
VipUser.prototype=new User()
VipUser.prototype.constructor=VipUser
VipUser.prototype.showLevel=function(){
alert(this.level)
}
var user=new VipUser('yan',1234,5)
user.showName()
user.showLevel()
ES6写法
- super——超类(父类)
class User{
constructor(name,pass){
this.pass=pass
this.name=name
}
showName(){
alert(this.name)
}
showPass(){
alert(this.pass)
}
}
class VipUser extends User{
constructor(name,pass,level){
super(name,pass)
this.level=level
}
showLevel(){
alert(this.level)
}
}
var user=new VipUser('yan',1234,5)
user.showName()
user.showLevel()
面向对象应用——React
React:
- 组件化——一个组件就是一个class
- 依赖于JSX(即babel browser.js)
jsx——js的扩展版
<div id="div1">
</div>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script crossorigin src="https://cdn.bootcss.com/babel-standalone/6.25.0/babel.js"></script>
<script type="text/babel">
class Test extends React.Component{
constructor(...args){
super(...args)
}
render(){
return <h1>123</h1>
}
}
class Item extends React.Component{
constructor(...args){
super(...args)
}
render(){
return <li>{this.props.str}</li>
}
}
class List extends React.Component{
constructor(...args){
super(...args)
}
render(){
let aItems=[]
for(let i=0;i<this.props.arr.length;i++){
aItems.push(<Item key={i} str={this.props.arr[i]}></Item>)
}
return <ul>
{aItems}
</ul>
// return <ul> es6写法
// {this.props.arr.map(a=><Item key={a} str={a}></Item>)}
// </ul>
}
}
window.onload=function() {
let oDiv=document.getElementById("div1")
ReactDOM.render(
<List arr={['a','b','v']}></List>,
oDiv
)
}
</script>
json
JSON对象
- JSON.stringfy(json对象)
- JSON.parse(json字符串)
JSON简写
-
key和value一样可以简写
let a=2,b=5 let json2={a:a,b:b}==>{a,b}
-
方法存在的话:和function一起删掉
let json2={ a:a, b:b, show(){ alert(this.a) } }
JSON字符串标准写法
- 只能用双引号
- 所有的key必须用双引号标起来
'{"a":12,"b":5}'
Promise
1. 异步请求/操作
- 异步:操作之间没有任何关系,可以同时进行多个操作
- 同步:同时只能做一件事
2. 优缺点
- 异步缺点:代码更复杂
- 同步优点:代码简单
//异步操作读取数据
ajax('./banners',function(banner_data){
ajax('./hotItems',function(hotItem_data){
ajax('./slides',function(slide_data){
},function(){alert("读取失败")})
},function(){alert("读取失败")})
},function(){alert("读取失败")})
//同步操作数据
let banner_data=ajax_sync('./banners')
let hotItem_data=ajax_sync('./hotItems')
let slide_data=ajax_sync('./slides')
3. Promise——清除异步操作
- 本质:用同步一样的方式写异步
- 用法:
基本的封装ajax
let p1=new Promise(function(resolve,reject){
//异步代码
//resolve成功
//reject失败
$.ajax({
url:'https://easy-mock.com/mock/5cadb508b56fc13f6206ad0e/example/arr.txt',
type:'get',
dataType:'json',
success(data){
resolve(data)
},
error(err){
reject(err)
}
})
})
p1.then(function(){},function(){}) //resolv reject
Promise.all()函数
let p1=new Promise(function(resolve,reject){
//异步代码
//resolve成功
//reject失败
$.ajax({
url:'https://easy-mock.com/mock/5cadb508b56fc13f6206ad0e/example/arr.txt',
type:'get',
dataType:'json',
success(data){
resolve(data)
},
error(err){
reject(err)
}
})
})
let p2=new Promise(function(resolve,reject){
$.ajax({
url:'https://easy-mock.com/mock/5cadb508b56fc13f6206ad0e/example/json.txt',
dataType:'json',
type:'get',
success:function(data){
resolve(data)
},
error:function(err){
reject(err)
}
})
})
Promise.all([p1,p2]).then(function(arr){
let [res1,res2]=arr
console.log(res1,res2)
},function(){
alert("至少一个失败")
})
通用封装
function createPromise(url){
return new Promise(function(resolve,reject){
//异步代码
//resolve成功
//reject失败
$.ajax({
url:url,
type:'get',
dataType:'json',
success(data){
resolve(data)
},
error(err){
reject(err)
}
})
})
}
Promise.all([createPromise("https://easy-mock.com/mock/5cadb508b56fc13f6206ad0e/example/arr.txt"),createPromise("https://easy-mock.com/mock/5cadb508b56fc13f6206ad0e/example/json.txt")]).then(function(arr){
let [res1,res2]=arr
console.log(res1,res2)
},function(){
alert("至少一个失败")
})
4. 有了promise之后的异步
Promise.all([$.ajax({]}),$.ajax({})]).then(
results=>{
//全部成功之后的操作
},err=>{
//失败
}
)
5. Promise其他用法
- Promise.race() 竞速,与all区别是:只要有一个文件请求成功了就用谁,就会返回resolve
generator 生成器,函数
- 普通函数
- 一路到底
- generator函数
- 中间能暂停
使用场景
- 请求数据
function 函数(){ //code ajax(xx,function(){ //code回调方式 }) //code } function *函数(){ //code yield ajax(xxx) //yield将整个生成函数分割成若干个普通小函数,通过next()依次执行函数 //code }
yield
- 传参-*********
第一个next没法给yield传参
function *show(){
alert(1)
let a=yield
alert(2)
}
let gen=show()
//如果第一个next想要传参的话直接同正常函数一样
function *show(num1,num2){
alert(`${num1},${num2}`)
alert(1)
let a=yield
alert(2)
}
let gen=show()
let gen=show(99,88)
gen.next(12)//第一个next没法给yield传参
gen.next(5)
- 返回
function *show(){
alert('a')
yield 12
alert('b')
}
let gen=show()
res1=gen.next()
console.log(res1)//{value:12,done:false}
res2=gen.next()
console.log(res2)//{value:undefined(取决于函数体中的return值),done:true}
for…in 和for…of的区别
- 循环数组
前者遍历出下标,后者遍历出值 - json
前者遍历出键(key),后者不能用
复习
- 变量 let const
声明方式 | 能否重复声明 | 作用域 | 类型 | 是否支持变量提升 |
---|---|---|---|---|
var | 能 | 函数级 | 变量 | 是,undefined |
let | 不能,不允许在相同作用域内,重复声明同一个变量 | 块级 | 变量 | 否,referrenceError:is not defined |
const | 不能 | 块级 | 常量 | 否 |
暂时性死区:在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)
- 箭头函数
- 方便
- 如果只有一个参数,()可以省略
- 如果只有一个语句且为return,{}可以省略
- 修正this
- 只会从自己的作用域链的上一层继承this
- 箭头函数没有自己的this指针,通过 call() 或 apply() 方法调用一个函数时,只能传递参数
- 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。所以this对象的指向是可变的,但是在箭头函数中,它是固定的。
- 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
- 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替
- 不可以使用yield命令,因此箭头函数不能用作 Generator 函数
- 不适用场合
- 定义对象的方法,且该方法内部包括this。
- 需要动态this的时候,也不应使用箭头函数
作用域 :一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。
- 参数的扩展…rest
- 收集
- 扩展
- 默认参数
- 数组方法
- map 映射
- reduce 汇总
- filter 过滤
- forEach 循环
- 字符串
- startWith
- endWith
- 字符串模板
${a}xxx${b}
- Promise
- 封装异步操作
- Promise.all([]).then()
- generator
- 执行一半能暂停
- yield
- JSON
- JSON.stringfy()
- JSON.parse()
- 面向对象
- class Test{}
- 解构赋值
- 左右结构一样
- 右边是合法事情
- 声明赋值一次完成