網頁開發基礎--ES6

目錄

ES6基礎入門之let、const

變量聲明

let和var的主要區別

ES6之前的作用域

塊級作用域

let面試常見例子

const

const與let類似的特性

常量不可變

怎麼解決引用類型的常量可以被修改的問題?

ES6之前怎麼聲明常量?

ES6變量的解構賦值

數組的解構賦值

數組的解構賦值

更復雜的匹配規則

擴展運算符 ...

默認值

交換變量

接收多個函數返回值

對象的解構賦值

對象解構賦值的用法

稍微複雜的解構條件

擴展運算符 ...

如何對已經申明瞭的變量進行對象的解構賦值

默認值

對象的解構賦值的主要用途

字符串的解構賦值

數值與布爾值的解構賦值

函數參數的解構賦值


ES6基礎入門之let、const

變量聲明

var聲明

var name='hiyori'

直接使用

window.location.href===location.href

說明:這種不加var聲明的定義方式,相當於在全局對象window上掛了一個屬性,會造成全局對象污染 ,不建議這麼做

let和var的主要區別

  • let聲明的變量只在當前(塊級)作用域內有效
  • let聲明的變量不能被重複聲明
  • let不存在變量提升

ES6之前的作用域

全局作用域、函數作用域、eval作用域

塊級作用域

  • 通俗的講,就是一堆花括號中的區域{...}
  • 塊級作用域可以嵌套
/* let聲明的變量只在當前(塊級)作用域內有效 */
//example1
{
  var a = 1;
  let b = 2;
}
console.log(a);    //打印a
console.log(b);    //出了塊級作用域,報錯信息爲未定義
 
//example2
{
  let a = 1;
  {
    console.log(a);    //這裏屬於a的作用範圍,打印1
    let b = 2;
  }
  console.log(b);    //這裏不屬於b的作用範圍,報錯
} 
 
//example3
for (let i = 0; i < 3; i++) {
 
};
console.log(i);    //報錯
 
for (var i = 0; i < 3; i++) {
  console.log(i);
};
console.log(i);    //打印3,var定義的i並不會被釋放,因爲初始化時定義的i相當於是在循環語句的作用域之外定義的
/* 使用let或者const聲明的變量不能被重新聲明 */
var dad = '我是爸爸!';
var dad;
console.log(dad);    //重新聲明,沒有被賦值,該變量還是'我是爸爸'
var dad = '我纔是爸爸!';
console.log(dad);    //修改爲新的值
 
let son = '我是兒子';
let son;    //報錯,提示son已被聲明過
let son = '我纔是兒子';    //報錯,提示son已被聲明過
/* let不存在變量提升 */
console.log(dad);    //undefined
var dad='我是爸爸';
//以上情形就是因爲變量提升
//預解析時會先解析帶有var關鍵字的變量,並賦值爲undefined,執行代碼時才賦真正的值
//相當於
var dad;    //變量聲明被拉到最前面,而後賦值
console.log(dad);
dad='我是爸爸';
 
console.log(dad);    //報錯,提示未定義該變量
let dad='我是爸爸';
//用let定義的變量不會把聲明拉到最前面,因此不具有變量提升
//暫存死區
var monkey = '我是美猴王';
{
  console.log(monkey);    //我是..
  var monkey = '我覺得我還能再搶救一下!';
}
console.log(monkey);    //我覺得..
 
let monkey = '我是美猴王';
{
  console.log(monkey);    //報錯
  let monkey = '我覺得我還能再搶救一下!';
}
console.log(monkey);

let面試常見例子

q: 生成十個按鈕 每個按點擊的時候彈出1 - 10
var i = 0;
for (i = 1; i <= 10; i ++) {
  (function(i) {
    var btn = document.createElement('button');
    btn.innerText = i;
    btn.onclick = function() {
      alert(i)
    };
    document.body.appendChild(btn);
  })(i);
}
    //在外面加上自執行匿名函數,就會形成獨立的函數作用域,i作爲參數傳進來,在作用域中獲得的就是實時更新的i
    //如果沒有定義一個自執行的function,那麼這裏每次點擊彈出的都是11
    //因爲發生點擊事件後要去尋找i,本層找不到就會到上一層去找,上一層的i在循環結束後值爲11
    //因此事件中獲取到的i的值也是11
 
 
//使用let定義,可以實現和添加自執行函數一樣的效果
for (let i = 1; i <= 10; i ++) {
  var btn = document.createElement('button');
  btn.innerText = i;
  btn.onclick = function() {
    alert(i)    
  };
  document.body.appendChild(btn);
}

const

常量——不可改變的量

和聲明變量一樣,基本只是關鍵字的區別

常量必須在聲明的時候賦值,否則報錯:Missing initiaizer in const declaration

const a;    //不賦值,會報錯
var b=2;
let c;

const與let類似的特性

不能重複聲明

不存在變量提升

只在當前(塊級)作用域內有效

常量不可變

一旦聲明常量,就不能再改變

但常量爲引用類型的時候,不能保證不可變

const NAME='xh';
NAME='xm';    //報錯,提示常量不能被修改

說明:const只能保證引用常量的地址不變,不能保證它裏面的值不變。

//對象
const xiaoming={
    age:14;
    name:'xm';
}
xiaoming.age=22;    //允許修改
xiaoming={};    //報錯,不允許被修改,因爲相當於把一個新的地址給了xiaoming這個常引用對象
 
//數組
const ARR=[];
ARR.push(1);    //允許添加
ARR=[];    //報錯,不允許被修改,還是相當於把一個新的地址給了ARR這個常引用數組

怎麼解決引用類型的常量可以被修改的問題?

Object.freeze()

const xiaoming = {
  age: 14,
  name: '小明'
};
Object.freeze(xiaoming);    //xiaoming對象中的值也不允許被修改了
console.log(xiaoming);
xiaoming.age = 22;    //不報錯,但不會發生改變
xiaoming.dd = 11;    //不報錯,但不會發生改變
console.log(xiaoming);
 
const ARR = [];
Object.freeze(ARR);    //ARR數組中的值也不允許被修改了
ARR.push(1);    //報錯,提示不能被擴展
console.log(ARR);

ES6之前怎麼聲明常量?

用var聲明,假裝是常量

var BASE_COLOR = '#ff0000';

Object.defineProperty();

var CST = {a: 1};
Object.defineProperty(CST, 'a', {
  writable: false
});
//writable:只讀,不能被修改
Object.seal(CST);    //只能防止被擴展
//Object.seal+writable:false才能達到freeze()的效果

自行封裝一個freeze()

// 1. 遍歷屬性和方法
// 2. 修改遍歷到的屬性的描述
// 3. Object.seal()
 
Object.defineProperty(Object, 'freezePolyfill', {
  value: function(obj) {
    var i;
    for (i in obj) {
      if (obj.hasOwnProperty(i)) {
        Object.defineProperty(obj, i, {
          writable: false    //每個屬性都不能被修改
        });
      }
    }
    Object.seal(obj);    //整個對象不能被擴展
  }
});
 
const xiaoming = {
  age: 14,
  name: '小明',
  obj: {
    a: 1
  }
};
 
Object.freezePolyfill(xiaoming);

ES6變量的解構賦值

解構賦值語法是一個JavaScript表達式,這使得可以將值從數組或屬性從對象提取到不同的變量中

數組的解構賦值

數組的解構賦值

// 數組的解構賦值
 
const arr = [1, 2, 3, 4];
let [a, b, c, d] = arr;
 
//會根據元素在數組中所在的位置一一對應匹配,a=1,b=2……

更復雜的匹配規則

// 更復雜的匹配規則
 
const arr = ['a', 'b', ['c', 'd', ['e', 'f', 'g']]];
 
const [ , b] = arr;    //只返回b
const [ , , g] = ['e', 'f', 'g']    //只返回g
const [ , , [ , , g]] = ['c', 'd', ['e', 'f', 'g']];    //只返回g
const [ , , [ , , [ , , g]]] = arr;    //只返回g

擴展運算符 ...

// 擴展運算符  ...
 
const arr1 = [1, 2, 3];
const arr2 = ['a', 'b'];
const arr3 = ['zz', 1];
const arr4 = [...arr1, ...arr2, ...arr3];    //可以把arr1、arr2、arr3合併起來
 
const arr = [1, 2, 3, 4, 5, 6];
const [a, b, ...c] = arr;    //會把3,4,5,6作爲一個數組賦給c
 
const [a, b, ...c,d] = arr;    //錯誤

注意:帶擴展運算符的變量後面不能再有其他變量,因爲擴展運算符就是用來取最後幾個元素進行合併的

默認值

// 默認值
 
const arr = [1, null, undefined];
const [a, b = 2, c, d = 'aaa'] = arr;    //設置默認值,當匹配到undefined時,就使用默認值
 
//a=1,b=null,c=undefined,d='aaa'

說明:解構賦值時沒有匹配到的就被賦值爲undefined 

交換變量

// 交換變量
 
let a = 20;
let b = 10;
 
//方法①
let temp;
temp = a;
a = b;
b = temp;
 
//方法②,利用解構賦值
[a, b] = [b, a];

接收多個  函數返回值

// 接收多個 函數返回值
 
function getUserInfo(id) {
  // .. ajax
 
  return [
    true,
    {
      name: '小明',
      gender: '女',
      id: id
    },
    '請求成功'
  ];
};
 
const [status, data, msg] = getUserInfo(123);
 
//status匹配到函數返回值第一項布爾值,data匹配到函數返回值第二項對象,msg匹配到函數返回值第三項文字

對象的解構賦值

對象的解構賦值與數組的解構賦值相似

等號左右兩邊都爲對象結構

const {a,b}={a:1,b:2};

左邊的{}中爲需要賦值的變量

右邊爲需要解構的對象

對象解構賦值的用法

// 對象的解構賦值
 
const obj = {
	saber: '阿爾託利亞',
	archer: '衛宮'
};
const { saber, archer1 } = obj;    //archer屬性名不匹配,archer1的值是undefined

注意:對象的解構賦值要求不同對象的屬性名要一致,才能匹配。因爲數組是有序的,而對象是無序的,必須用屬性名去匹配,而不是用位置去匹配。

稍微複雜的解構條件

// 稍微複雜的解構條件
 
const player = {
	nickname: '感情的戲∫我沒演技∆',
	master: '東海龍王',
	skill: [{
		skillName: '龍吟',
		mp: '100',
		time: 6000
	},{
		skillName: '龍捲雨擊',
		mp: '400',
		time: 3000
	},{
		skillName: '龍騰',
		mp: '900',
		time: 60000
	}]
};
 
const { nickname } = player;    //返回感情的戲∫我沒演技∆
const { master } = player;    //返回東海龍王
const { skill: [ skill1, { skillName }, { skillName: sklName } ] } = player;    
//保持格式一致,就可以解構skill裏的屬性
//對數組進行賦值時變量名可以隨便起,skill1獲得skill數組的第一項,skillName獲得數組第二項中的skillName龍捲雨擊
//這時如果想要獲得skill數組第三項的skillName再次使用{skillName}是不行的,因爲const聲明的變量中已經有skillName了
//我們需要另外起一個名字,只要在屬性名後面加上:新名字,就可以解決這個問題,意思是把skillName中的值賦給sklName
 
const { skill } = player;    //返回一個數組
const [ skill1 ] = skill;    //skill是一個數組,skill1是數組元素的第一項——龍吟,100,6000
const { skill:[skill1] }=player;    //與上一行完全一樣,但不會取到skill

擴展運算符 ...

// 結合擴展運算符
 
const obj = {
	saber: '阿爾託利亞',
	archer: '衛宮',
	lancer: '瑟坦達'
};
 
const { saber, ...oth } = obj;    //會把除了saber以外的剩下所有項賦值給oth
const obj1 = {
	archer: '衛宮',
	lancer: '瑟坦達'
}
 
const obj = {
	saber: '阿爾託利亞',
	...obj1,    //會把obj1所有屬性合併成一個對象
};

如何對已經申明瞭的變量進行對象的解構賦值

// 如何對已經申明瞭的變量進行對象的解構賦值
 
let age;
const obj = {
	name: '小明',
	age: 22
};
 
({ age } = obj);
//{age}外面如果不加(),會被編譯器理解成塊級作用域,然後報錯。
 
//最好的方法是帶上變量聲明
const obj = {
	name: '小明',
	age: 22
};
let {age}=obj;

默認值

// 默認值
 
let girlfriend = {
	name: '小紅',
	age: undefined,
};
 
let { name, age = 24, hobby = ['學習'] } = girlfriend;
//name='小紅',age=24

對象的解構賦值的主要用途

提取對象屬性

// 提取對象屬性
 
const { name, hobby: [ hobby1 ], hobby } = {    //把hobby值賦給hobby1,再定義一個hobby就獲取到對象的hobby屬性值
	name: '小紅',
	hobby: ['學習']
};

使用對象傳入亂序的函數參數

function AJAX({    //傳參時解構賦值,可以不按順序賦值,如果type沒有設置默認爲get
	url,
	data,
	type = 'get'
}) {
	// var type = option.type || 'get';
	// console.log(option);
	console.log(type);
};
AJAX({
	data: {a: 1},
	url: '/getinfo',
});

獲取多個函數返回值

// 獲取多個 函數返回值
 
function getUserInfo(uid) {
	// ...ajax
	return {
		status: true,
		data: { name: '小紅' },
		msg: '請求成功'
	};
};
const { status, data, msg: message } = getUserInfo(123);

字符串的解構賦值

// 字符串的結構賦值
const str = 'I am the bone of my sword'; // 我是劍骨頭
 
const [ a, b ,c, ...oth ] = str;    
//a=I,b= ,c=a,oth=m the bone of my sword,注意這裏oth是一個數組,每個字符是一個數組元素
 
const [ ...spStr1 ] = str;    //spStr1是一個數組,每個數組元素是str的一個字符
const spStr2 = str.split('');    //同上一句效果一樣
const spStr3 = [ ...str ];    //同上一句效果一樣
 
// 提取屬性
 
const { length, split } = str;

數值與布爾值的解構賦值

// 數值與布爾值的解構賦值
 
const { valueOf: vo } = 1;
const { toString: ts } = false;

函數參數的解構賦值

// 函數參數的解構賦值
 
function swap([x, y]) {
	return [y, x];
};
 
let arr = [1, 2];
arr = swap(arr);
 
//定義一個Computer的構造函數
function Computer({
	cpu,
	memory,
	software = ['ie6'],
	OS = 'windows 3.5'
}) {
 
	console.log(cpu);
	console.log(memory);
	console.log(software);
	console.log(OS);
 
};
 
//聲明一個Computer對象
new Computer({
	memory: '128G',
	cpu: '80286',
	OS: 'windows 10'
});

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章