摘要:使用定義常量應該注意,的作用域與命令相同只在聲明所在的塊級作用域內有效。,命令聲明的常量也是不提升,同樣存在暫時性死區,只能在聲明的位置后面使用。使用的時候,也是直接對類使用命令,跟構造函數的用法完全一致。執行父級的構造函數。
一,let塊級作用域
由于js的歷史原因。javascript里的es6規范之前,只要函數作用域。當寫一些大型的項目代碼中,很容易產生全局變量,例如:
點擊每個按鈕,都結果都是4;
0,1,2,3
當使用let定義變量的時候。點擊每個按鈕,都結果顯示的都是對應的i值。
現在我們可以使用let 定義塊級變量。 只在代碼塊{}內生效;
如:
彈1
報錯
使用塊級應該注意:
1.塊級作用域
for(var i = 0; i < 10; i++){} console.log(i); //10 for(let j = 0; j < 10; j++){} console.log(j); //"ReferenceError: j is not defined
2.不存在變量提升
會報錯,ReferenceError
console.log(a); // 輸出undefined console.log(b); // 報錯ReferenceError console.log(c); // 報錯ReferenceError var a = 2; let b = 2;
3.暫時性死區(TDZ)
只要進入當前塊級作用域,所使用的變量已經存在了,但在聲明之前都屬于死區,不可進行操作。
typeof x; // ReferenceError typeof y // undefined let x;
4.不允許重復聲明
let x = 1; let x; // "SyntaxError: Identifier "x" has already been declared var y = 2; var y = 3; // y = 3
5.聲明的全局變量不再是window的屬性
"use strict"; var a = 1; console.log(window.a) // 1 let b = 1; console.log(window.b) // undefined二,const定義常量
const聲明一個只讀的常量。一旦聲明,常量的值就不能改變
const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
上面代碼表明改變常量的值會報錯。
const聲明的變量不得改變值,這意味著,const一旦聲明變量,就必須立即初始化,不能留到以后賦值。
const foo; // SyntaxError: Missing initializer in const declaration 使用const定義常量應該注意:
1,const的作用域與let命令相同:只在聲明所在的塊級作用域內有效。
2,const命令聲明的常量也是不提升,同樣存在暫時性死區,只能在聲明的位置后面使用。
3,const聲明的常量,也與let一樣不可重復聲明。
const本質:
const實際上保證的并不是變量值不得改動,而是變量指向的那個內存地址不得改變。對于簡單類型的數據(數值,字符串,布爾值),值就是指向的那個內存地址,因此等同于常量。但是對于復合類型的數據(注意是對象和數組),變量指向的是內存地址,保存的只是一個指針,const只能保證這個指針是固定的,至于他指向的數據機構是不是可變的,就不能控制了,因此,將一個對象聲明為常量是非常小心的。
const foo = {}; // 為 foo 添加一個屬性,可以成功 foo.prop = 123; foo.prop // 123 // 將 foo 指向另一個對象,就會報錯 foo = {}; // TypeError: "foo" is read-only
上面代碼中,常量foo儲存的是一個地址,這個地址指向一個對象。不可變的只是這個地址,即不能把foo指向另一個地址,但對象本身是可變的,所以依然可以為其添加新屬性。
下面是另一個例子。
const a = []; a.push("Hello"); // 可執行 a.length = 0; // 可執行 a = ["Dave"]; // 報錯 上面代碼中,常量a是一個數組,這個數組本身是可寫的,但是如果將另一個數組賦值給a,就會報錯。
ES6 聲明變量的六種方法 ES5 只有兩種聲明變量的方法:var命令和function命令。ES6 除了添加let和const命令,后面章節還會提到,另外兩種聲明變量的方法:import命令和class命令。所以,ES6 一共有 6 種聲明變量的方法。三,函數參數擴展
rest 參數
ES6 引入 rest 參數(形式為...變量名),用于獲取函數的多余參數,這樣就不需要使用arguments對象了。rest 參數搭配的變量是一個數組,該變量將多余的參數放入數組中。
function add(...values) { let sum = 0; for (var val of values) { sum += val; } return sum; } console.log(add(2, 5, 3)) // 10
注意在es6中rest參數只可以是形參的最后一位參數。不然會報錯
function add(...values,a) { let sum = 0; for (var val of values) { sum += val; } return sum; } console.log(add(2, 5, 3))四,箭頭函數:
之前我們定義一個函數是這樣的:
let add=function () { alert(123) } add()
現在我們可以改成箭頭函數
let ale=()=>{alert(234)}
ale()
改成箭頭函數無非就是把代碼簡寫了,應該注意一下三點:
1,把普通函數的function換成=>.
2,如果只有一個參數,那么()可省略不寫。
2,如果只有一個return 那么{}可省略不寫。
例如:
1,數組的解構賦值
基本用法
ES6 允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構。
以前,為變量賦值,只能直接指定值。
let a=1 let b=2 let c=3
ES6 允許寫成下面這樣。
let [a, b, c] = [1, 2, 3];
上面代碼表示,可以從數組中提取值,按照對應位置,對變量賦值。
本質上,這種寫法屬于“模式匹配”,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。下面是一些使用嵌套數組進行解構的例子
let [foo, [[bar], baz]] = [1, [[2], 3]]; foo // 1 bar // 2 baz // 3 let [ , , third] = ["foo", "bar", "baz"]; third // "baz" let [x, , y] = [1, 2, 3]; x // 1 y // 3 let [head, ...tail] = [1, 2, 3, 4]; head // 1 tail // [2, 3, 4] let [x, y, ...z] = ["a"]; x // "a" y // undefined z // []
如果解構不成功,變量的值就等于undefined。以下兩種情況都屬于解構不成功,foo的值都會等于undefined。
let [foo] = []; let [bar, foo] = [1];五,數組
es6中數組有常用的四個方法依次是:
map ----映射 一個對一個
reduce -----匯總 一堆出來一個
filter -----過濾器
forEach -----循環(迭代)
1.map用法
也可改成箭頭函數
循環數組,每次都乘2倍,并返回新數組
2.reduce
let arr=[2,14,31,1,4,3] arr.reduce(function(a,b,c){ alert(a+","+b+","+c) })
先看彈什么結果,依次是
先看結果。明顯 c參數是下標index,但是有不是0開始。
b是當前的數。 其實a就是最終結果,把上一次算好的數當成了這次的中間結果。 let arr=[2,14,31,1,4,3] let result=arr.reduce(function(tmp,item,index){ return tmp+item }) alert(result)
這就是求和的方式
reduce 流程圖
求平均數
let arr=[2,14,31,1,4,3] let result=arr.reduce(function(tmp,item,index){ if(index !=arr.length-1){ //不是最后一項 return tmp+item }else{ //最后一項 return (tmp+item)/arr.length } }) alert(result)
3.filter 過濾器 留下符合條件的一部分;
通過filter里面的function里返回的true和false判斷留或者不留。
let arr=[2,14,31,1,4,3] let arr2=arr.filter(()=>{ return true }) alert(arr2) //[2,14,31,1,4,3]
因為返回的true所以都留下了
let arr=[2,14,31,1,4,3] let arr2=arr.filter(()=>{ return false }) alert(arr2) // [ ]
因為返回的false所以都不留下
下面的取可以被3整除的數
let arr=[2,14,33,1,4,3,66] let arr2=arr.filter((item)=>{ if(item%3==0){ return true }else{ return false } }) alert(arr2) //33,3,66
由于item%3==0本身就是布爾值,所以直接可以return這個,即就可以返回符合條件的數。
所以可以寫成,
let arr=[2,14,33,1,4,3,66] let arr2=arr.filter((item)=>{ return item%3==0 }) alert(arr2) //33,3,66
還可以簡寫成箭頭函數
let arr=[2,14,33,1,4,3,66] let arr2=arr.filter(item=>item%3==0) alert(arr2) //33,3,66
4.forEach 就是普通的循環,無法就是寫法簡單一些,
let arr=[2,14,33,1,4,3,66] arr.forEach(item=>{ alert(item) })
它第二個參數是可選的,是index
let arr=[2,14,33] arr.forEach((item,index)=>{ alert(index+":"+item) }) //0:2 //1:14 //2:33六.字符串
(一):
1.includes():返回布爾值,表示是否找到了參數字符串。
2.startsWith():返回布爾值,表示參數字符串是否在原字符串的頭部。
3.endsWith():返回布爾值,表示參數字符串是否在原字符串的尾部。
includes()用法
let s = "Hello world!"; s.startsWith("Hello") // true s.endsWith("!") // true s.includes("o") // true
startsWith()用法
let str="git.baidu.com" switch(true) { case str.startsWith("www."): console.log("www網址") break; case str.startsWith("git."): console.log("git網址") break; default: console.log("其他網址") }
endsWith()用法
let str="1.jpg" switch(true) { case str.endsWith("txt"): console.log("txt文件") break; case str.endsWith("jpg"): console.log("jpg文件") break; default: console.log("其他網址") }
(二):模板字符串 (返單引號`)
$("#result").append( "There are " + basket.count + " " + "items in your basket, " + "" + basket.onSale + " are on sale!" );
大括號內部可以放入任意的 JavaScript 表達式,可以進行運算,以及引用對象屬性。
let x = 1; let y = 2; `${x} + ${y} = ${x + y}` // "1 + 2 = 3" `${x} + ${y * 2} = ${x + y * 2}` // "1 + 4 = 5" let obj = {x: 1, y: 2}; `${obj.x + obj.y}` // "3"
模板字符串之中還能調用函數。
function fn() { return "Hello World"; } `foo ${fn()} bar` // foo Hello World bar七.class
JavaScript 語言中,生成實例對象的傳統方法是通過構造函數。下面是一個例子。
function Point(x, y) { this.x = x; this.y = y; console.log(this,12) } Point.prototype.toString = function () { return "(" + this.x + ", " + this.y + ")"; }; var p = new Point(1, 2); console.log(typeof p.toString())
其不好的地方就是,構造函數和類混為一談了,別的語言(java)中構造函數就是構造函數,類就是類。
而且代碼寫了兩塊,方法通過prototype添加。還有就是這個是es6之前的方式生成對象。es6之前的js里中是沒有類的概念的,這些方式都是東拼西湊的。
寫到這里,可以暫時回顧一下es6之前的創造對象的時候 new 關鍵字都做了什么。
要創建 Person 的新實例,必須使用 new 操作符。以這種方式調用構造函數實際上會經歷以下 4
個步驟:
(1) 創建一個新對象;
(2) 將構造函數的作用域賦給新對象(因此 this 就指向了這個新對象) ;
(3) 執行構造函數中的代碼(為這個新對象添加屬性) ;
(4) 返回新對象。
new 操作符
在有上面的基礎概念的介紹之后,在加上new操作符,我們就能完成傳統面向對象的class + new的方式創建對象,在JavaScript中,我們將這類方式成為Pseudoclassical。
基于上面的例子,我們執行如下代碼
var obj = new Base();
new操作符具體干了什么呢?其實很簡單,就干了三件事情。
var obj = {}; obj.__proto__ = Base.prototype; Base.call(obj);
第一行,我們創建了一個空對象obj
第二行,我們將這個空對象的__proto__成員指向了Base函數對象prototype成員對象
第三行,我們將Base函數對象的this指針替換成obj,然后再調用Base函數,于是我們就給obj對象賦值了一個id成員變量,這個成員變量的值是”base”,關于call函數的用法。
如果我們給Base.prototype的對象添加一些函數會有什么效果呢?
例如代碼如下:
Base.prototype.toString = function() { return this.id; }
那么當我們使用new創建一個新對象的時候,根據__proto__的特性,toString這個方法也可以做新對象的方法被訪問到。于是我們看到了構造子中,我們來設置‘類’的成員變量(例如:例子中的id),構造子對象prototype中我們來設置‘類’的公共方法。于是通過函數對象和Javascript特有的__proto__與prototype成員及new操作符,模擬出類和類實例化的效果。
現在的es6中創作對象的方式就及其簡單。
class Point { constructor (x,y){ this.x=x; this.y=y } tostring (){ return "(" + this.x + ", " + this.y + ")"; } } let a=new Point(2,3) alert(typeof a.tostring()) //string
上面代碼定義了一個“類”,可以看到里面有一個constructor方法,這就是構造方法,而且this關鍵字則代表實例對象,也就是說,es5的構造函數Point,對應es6的point類的構造方法。
point類除了構造方法,還定義了一個tostring方法。注意,定義’類‘的方法時候,前面不需要加上function這個關鍵字,直接把函數定義進去級可以了。類外,方法之間不需要逗號分隔,加上會報錯。
ES6 的類,完全可以看作構造函數的另一種寫法。
class Point { // ... } typeof Point // "function" Point === Point.prototype.constructor // true
上面代碼表明,類的數據類型就是函數,類本身就指向構造函數。
使用的時候,也是直接對類使用new命令,跟構造函數的用法完全一致。
class Bar { doStuff() { console.log("stuff"); } } var b = new Bar(); b.doStuff() // "stuff"
構造函數的prototype屬性,在 ES6 的“類”上面繼續存在。事實上,類的所有方法都定義在類的prototype屬性上面。
class Point { constructor() { // ... } toString() { // ... } toValue() { // ... } } // 等同于 Point.prototype = { constructor() {}, toString() {}, toValue() {}, };
在類的實例上面調用方法,其實就是調用原型上的方法。
class B {} let b = new B(); b.constructor === B.prototype.constructor // true
上面代碼中,b是B類的實例,它的constructor方法就是B類原型的constructor方法。
由于類的方法都定義在prototype對象上面,所以類的新方法可以添加在prototype對象上面。Object.assign方法可以很方便地一次向類添加多個方法。
class Point { constructor(){ // ... } } Object.assign(Point.prototype, { toString(){}, toValue(){} });
prototype對象的constructor屬性,直接指向“類”的本身,這與 ES5 的行為是一致的。
Point.prototype.constructor === Point // true
另外,類的內部所有定義的方法,都是不可枚舉的(non-enumerable)。
七,面相對象
//es5中通過構造函數創建對象 function User (name,password){ this.name=name; this.password=password; console.log(this) } User.prototype.showname = function(){ alert(this.name) } User.prototype.showpass = function(){ alert(this.password) } var user=new User("lee","123") user.showname() user.showpass() // 之前的面相對象缺點: // 1,類和構造函數混為一談了。 // 2.方法添加到類(構造函數)外面。
es6中創建對象
// es6 class User { //User是類 constructor(name,password){ //constructor是構造函數 this.name=name; this.password=password } //方法寫在類里面,而且必須不能有function,多個方法之間不能有‘,’ showname(){ alert(this.name) }, showpass(){ alert(this.password) } } var user = new User ("wang","1234") user.showname() user.showpass()
繼承:
es5中的繼承:
// 繼承es5 function User (name,password){ this.name=name; this.password=password } User.prototype.showname=function(){ alert(this.name) } User.prototype.showpass=function(){ alert(this.password) } function Vipuser(name,password,level){ User.call(this,name,password) this.level=level } Vipuser.prototype=new User() //先new一下 Vipuser.prototype.constructor=Vipuser;//在補一下constructor,因為constructor亂了 Vipuser.prototype.showlevel=function(){ alert(this.level) } var vipuser=new Vipuser("LV","2323",8) vipuser.showname() vipuser.showpass() vipuser.showlevel()
es6中的繼承
// 繼承es6 class User{ constructor(name,password){ this.name=name; this.password=password; } showname(){ alert(this.name) } showpass(){ alert(this.password) } } class Vipuser extends User { constructor(name,password,level){ super(name,password)//super,超類,父類。執行父級的構造函數。繼承父級的屬性,相當于es5繼承中的User.call(this,name,password) this.level=level } showlevel(){ alert(this.level) } } var vipuser=new Vipuser("dawang","123",9) vipuser.showname() vipuser.showpass() vipuser.showlevel()
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94590.html
摘要:常量變量先說說常量和變量的概念吧,常量是說那種進行一次賦值后不會更改的值,比如說游戲賬戶的,變量是說賦值后有更改的需求的,比如游戲名,游戲密碼。常用實例交換變量的值提取數據解構賦值對提取對象中的數據,尤其有用。 本系列文章適合快速掌握 ES6 入門語法,想深入學習 ES6 的小伙伴可以看看阮一峰老師的《ECMAScript 6 入門》 學習 20% 的知識完成 80% 的工作 關于 ...
摘要:的翻譯文檔由的維護很多人說,阮老師已經有一本關于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。 JavaScript Promise 迷你書(中文版) 超詳細介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...
摘要:本系列文章適合快速掌握入門語法,想深入學習的小伙伴可以看看阮一峰老師的入門本篇文章是對之前文章的一個補充,可以使代碼更簡潔函數參數默認值在傳統語法中如果想設置函數默認值一般我們采用判斷的形式在新的語法中我們可以在參數聲明的同時賦予默認值參數 本系列文章適合快速掌握 ES6 入門語法,想深入學習 ES6 的小伙伴可以看看阮一峰老師的《ECMAScript 6 入門》 本篇文章是對之前文章...
摘要:結合工作中使用情況,簡單對進行一些復習總結,包括常用的語法,等,以及短時間內要上手需要重點學習的知識點不同工作環境可能有一些差別,主要參考鏈接是阮一峰的博客以及外文博客阮老師大部分文章是直接翻譯的這個博客簡介先說一下,是一個標準化組織,他們 結合工作中使用情況,簡單對es6進行一些復習總結,包括常用的語法,api等,以及短時間內要上手需要重點學習的知識點(不同工作環境可能有一些差別),...
摘要:在重寫完了的時候,就個人總結了一下常用的一些常用的語法和比優越的方面。參數字符串是否在原字符串的尾部返回布爾值。第一個大于的成員的索引方法,用于某個數組是否包含給定的值,返回一個布爾值。 1.前言 前幾天,用es6的語法重寫了我的一個代碼庫,說是重寫,其實改動的并不多,工作量不大。在重寫完了的時候,就個人總結了一下es6常用的一些常用的語法和比es5優越的方面。下面提到的語法可能也就是...
閱讀 1808·2021-11-23 09:51
閱讀 1268·2021-11-18 10:02
閱讀 963·2021-10-25 09:44
閱讀 2099·2019-08-26 18:36
閱讀 1619·2019-08-26 12:17
閱讀 1146·2019-08-26 11:59
閱讀 2746·2019-08-23 15:56
閱讀 3350·2019-08-23 15:05