let和const聲明變量
const 表示聲明常量 值不可以變化的量
const聲明的變量 值爲常量 不能修改
const修飾基本數據類型:
值不能被更改
const 修飾引用數據類型:
地址不能被更改
但是對象裏面的屬性跟方法可以被修改
var num=10;
num=99;
const a=99;
a=88; //報錯 不能爲常量重新分配值
const per={
name:"小砌牆",
age:16
}
per.name="小白";
console.log(per.name);//可以 const地址不可以修改 對象中的屬性和方法都可以修改
let: 塊級作用域變量
在js中沒有塊級作用域
這樣會導致什麼後果?
for(var i=0;i<10;i++){
}
if(true){
var num=10;
}
通過以上代碼 我們發現 i和num都是全局變量
因爲js本身沒有塊級作用域 所以儘管i和num是在
一個代碼塊裏面聲明的變量
但也是全局變量
這樣的代碼結構是有問題的
所以es6推出了 let變量
用let聲明的變量 只會在當前代碼塊的大括號裏面生效
大括號之外 再也無法找到這個變量
大大解決了 原來沒有塊級作用域的弊端
let聲明的變量 只會在當前大括號裏面的代碼開始運行時創建
這個大括號(塊級作用域) 運行完畢後銷燬
可以實現 用的時候創建 不用的時候銷燬
大大節省了內存空間
{
var num=10;
let a=99;
console.log(a);//99
}
console.log(num);//10
console.log(a);// a is not defined 報錯 這個變量不存在
let變量 沒有變量提升
{
console.log(a);// Cannot access 'a' before initialization 不能提前調用
let a=10;
}
let變量不能重名
let a=10;
let a=20;//Identifier 'a' has already been declared
//a變量已經被定義過 所以不能重複定義 let變量不能重名
暫時性死區
var num=10;
function show() {
num=99;//報錯 不會找到外部的num 而是找到內部的num
//但是num又是let聲明 不存在提升 所以報錯
let num;
}
用let解決異步函數數據變量 丟失問題
for(let i=0;i<10;i++){
setTimeout(function () {
console.log(i);
},0)
}
class創建類
綁定實例屬性 綁定實力方法 綁定靜態方法 綁定靜態屬性
class Person{
//綁定實例屬性
constructor(name,age) {
this.name=name;
this.age=age;
}
//綁定實力方法
eat(){
console.log("es6綁定方法喫喫喫!")
}
show(){
console.log("來吧展示!")
}
// 綁定靜態方法
static study(){
console.log("好好學習,天天向上")
}
}
// 綁定靜態屬性
Person.countru="China";
var per=new Person("果凍",1);
console.log(per.name);//果凍
console.log(per.age);//1
per.show();//來吧展示!
console.log(Person.countru);//China
console.log(Person.name);//自帶的 Person
class繼承
extends關鍵字
* es5中 構造函數之間 不能實現真正的繼承
* 所以也就無法調用 父類構造函數裏面的實例方法
*
* 但是es6的extends繼承 子類對象卻能調用父類裏面的方法
*
* 所以class語法更高級
*
* 但是 再高級也是語法糖
//繼承上邊的筆記的代碼
class Student extends Person{
constructor(name,age,hobby) {
super(name,age);
this.hobby=hobby;
}
work(){
console.log("好好!聽課!")
}
}
var stu=new Student("茄子",2,"溜溜~");
//子類繼承父類 就能調用父類裏面的 實例屬性跟實例方法
console.log(stu.name);
console.log(stu.age);
stu.show();
//除了能夠擁有父類的功能以外 還可以推出自己更強大的功能
//所以 子類往往比父類更加強大
stu.work();
//父類的靜態方法 也被繼承
Student.study();
//父類的靜態屬性 也被繼承
console.log(Student.countru);
console.log(Student.name);
Promise
Promise對象的格式寫法:
在異步函數裏面 通過return 返回一個 newPromise對象
Promise的構造函數裏面 傳入一個回調
回調的參數是兩個: resolve 和reject
格式:
function 異步函數(){
return new Promise(function(resolve,reject){
這裏面寫原來異步函數的異步代碼
如果計算正確 調用 resolve方法 傳入計算結果
如果計算錯誤 調用reject方法 傳入錯誤信息參數
})
}
外部 調用異步函數 接收到Promise對象
使用Promise對象 調用then方法 匹配正確結果
調用catch方法 匹配錯誤結果
then和catch都是參數是回調函數
var promise=異步函數();
promise.then(function(data){
一旦內部的promise對象調用了 resolve方法
那麼then就會被觸發
data就是resolve傳入的正確結果
})
promise.catch(function(err){
一旦內部的promise對象調用了 reject方法
那麼catch就會被觸發
err 就是reject方法傳入的錯誤結果
})
function async(a,b) {
return new Promise(function (resolve,reject) {
setTimeout(function () {
if(typeof a!="number"){
reject("你傳入的a參數不是數值型!!!");
return;
}
var result=a+b;
// 計算結果正確 調用 resolve
resolve(result);
},0)
})
}
接收Promise對象
/*var promise=async(1,2);
//獲取正確的結果
promise.then(function (data) {
console.log(data);
})
then方法和catch方法 都會返回當前promise對象
所以可以鏈式編程
catch只能有一個 then可以有好多個
var pro1=async("xx",6);
pro1.then(function (data) {
alert("匹配到了then")
console.log(data);
})
.catch(function (err) {
console.log(err);
})
在promise語法中,
then可以出現好多個 但是catch只能有一個
有兩個也只會觸發第一個
因爲 在不停的then then then過程中
如果都沒有計算 錯誤 那麼就會then執行下去 一直到最後一個
如果中間只要出現錯誤 直接匹配catch 剩下的then不執行了
在then這個鏈式編程中 catch寫到鏈的前邊和後邊效果一樣
但是一般 潛規則都是寫在最後
function asy(a,b) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
if(typeof a!="number"||typeof b!="number"){
reject("傳入的參數不是數值!");
return;
}
resolve(a+b);
},0)
})
}
var promise=asy(1,2);
promise.then(function (data) {
console.log(data); // 3
if(data>0){
return asy(data,3);
}
}).then(function (data) {
console.log(data); // 6
if(data>0){
return asy("xx",4);//匹配錯誤的位置
}
}).then(function (data) {
console.log(data); //匹配到錯誤 傳入的參數不是數值!
if(data>0){
return asy(data,5);
}
}).then(function (data) {
console.log(data); //上邊錯誤 運行不到這一個
}).catch(function (err) {
console.log("匹配到錯誤",err)
})
驗證表單案例
const user={
username:"",
password:"",
checkName:()=>new Promise((resolve, reject) => setTimeout(()=>{
if(/^\w{6,15}$/.test(user.username)){
resolve("用戶名格式正確")
}else{
reject("用戶名格式錯誤")
}
},0)),
checkPwd:()=>new Promise((resolve, reject) => setTimeout(()=>{
if(/^\w{6,15}$/.test(user.password)){
resolve("密碼格式正確")
}else{
reject("密碼格式錯誤")
}
},0)),
/* checkGender:function (success,error) {
// return new Promise()
},
checkAge:function (success,error) {
// return new Promise()
},
checkVip:function (success,error) {
// return new Promise()
}*/
}
user.username="xiaoqiang";
user.password="123456";
user.checkName()
.then((data)=>user.checkPwd())
.then((data)=>{
console.log("可以註冊了!",data)
}).catch((err)=>{
console.log("不能註冊",err);
})