昨天說到了《從壹開始先後端分離 [ Vue2.0+.NET Core2.1] 十五 ║ Vue前篇:JS對象&字面量&this》,經過整體來看,好像你們對這一塊不是很感興趣,嗯~~這一塊確實挺枯燥的,不能直接拿來代碼跑一下那種,不過仍是得說下去,繼續加油吧!若是你們對昨天的小demo練習的話,相信如今已經對JS的面向對象寫法很熟悉了,若是嵌套字面量定義函數,如何使用this關鍵字指向。今天呢,主要說一下ES6中的一些特性技巧,而後簡單說一下模塊化的問題,好啦,開始今天的講解~javascript
仍是老規矩,一言不合就是上代碼html
str1 = 'Hello JS!'; function fun1() { var str1 = 'Hello C#!'; } fun1(); alert(str1);
你們猜猜,最後會彈出來哪一句話?前端
這些定義網上一大堆,不過仍是粘出來,你們能夠統一看一下,簡單瞭解瞭解:vue
一、定義java
ECMAScript 6是JavaScript語言的下一代標準,在2015年6月正式發佈。它的目標,是使得JavaScript語言能夠用來編寫複雜的大型應用程序,成爲企業級開發語言。node
標準的制定者有計劃,之後每一年發佈一次標準,使用年份做爲標準的版本。由於當前版本的ES6是在2015年發佈的,因此又稱ECMAScript 2015。也就是說,ES6就是ES2015,下一年應該會發布小幅修訂的ES2016。webpack
二、有哪些新的變化ios
編程語言JavaScript是ECMAScript的實現和擴展,由ECMA(一個相似W3C的標準組織)參與進行標準化。ECMAScript定義了:web
ECMAScript標準不定義HTML或CSS的相關功能,也不定義相似DOM(文檔對象模型)的Web API,這些都在獨立的標準中進行定義。ECMAScript涵蓋了各類環境中JS的使用場景,不管是瀏覽器環境仍是相似node.js的非瀏覽器環境。npm
三、ECMAScript和JavaScript的關係
1996年11月,JavaScript的創造者Netscape公司,決定將JavaScript提交給國際標準化組織ECMA,但願這種語言可以成爲國際標準。次年,ECMA發佈262號標準文件(ECMA-262)的初版,規定了瀏覽器腳本語言的標準,並將這種語言稱爲ECMAScript,這個版本就是1.0版。
該標準從一開始就是針對JavaScript語言制定的,可是之因此不叫JavaScript,有兩個緣由。一是商標,Java是Sun公司的商標,根據受權協議,只有Netscape公司能夠合法地使用JavaScript這個名字,且JavaScript自己也已經被Netscape公司註冊爲商標。二是想體現這門語言的制定者是ECMA,不是Netscape,這樣有利於保證這門語言的開放性和中立性。
所以,ECMAScript和JavaScript的關係是,前者是後者的規格,後者是前者的一種實現
這裏先說下,做用域的問題
一、ES6以前,JavaScript 並無塊級做用域,所謂的塊,就是大括號裏面的語句所組成的代碼塊,好比
function blog(bl) { if (bl) { var foo = "Blog"; } console.log(foo); } blog(true); //=> Blog
二、雖然變量foo 位於 if
語句的代碼塊中,可是 JavaScript 並無塊級做用域的概念,所以被添加到了當前的執行環境 - 即函數中,在函數內均可以訪問到。
所以:var 定義的變量是函數級做用域,做用範圍是在函數開始階段和函數執行完成以前內都是存在的;
而且若是該函數內部還存在匿名函數等特殊函數,這個 var 出的變量在匿名函數中仍然能夠用;
三、在ES出現後,定義了一個新的命名方式 let
function Blog(bool) { if (bool) { let foo = "Blog"; } else { console.log(foo); } } Blog(false); //這裏會報錯 Uncaught ReferenceError: foo is not defined
所以,使用 let,上述問題徹底解決,let出的變量做用域是 塊做用域,在離開某一代碼塊,該變量就會被銷燬不存在
應當儘量的避免用 var,用 let 來代替,除非你須要用到變量提高。
四、隨着面向對象思惟的出現,JS也出現了常量的定義 const
const 與 let 的基本用法相同,定義的變量都具備塊級做用域,也不會發生變量提高。不一樣的地方在於,const 定義的變量,只能賦值一次。
const foo='Blog'; function Blog(bool) { if (bool) { foo = "Vue"; } else { console.log(foo); } } Blog(true); //這裏會報錯 Identifier 'foo' has already been declared
所以const多用做不發生變化的變量定義,好比定義月份,或者,星期等:const months = [];
還記得昨天的那個小demo麼,今天再說一個地方
var obj = { data: { books: "", price: 0, bookObj: null }, bind() {//注意!ES6 中,可使用這種方法簡寫函數,等價於 bind: function () { var that = this; //普通函數 //$(".ok").click(function () {
// console.log(this);//這個時候,this,就是 .ok 這個Html標籤 // var bookItem = that.data.bookObj; // var _parice = $(bookItem).data("price"); // var _book = $(bookItem).data("book"); // that.data.books += _book + ","; // that.data.price += parseInt(_parice); // that.show(); //}); //箭頭函數 $(".ok").click(() => { var bookItem = this.data.bookObj;//在箭頭函數中,this指向的是定義函數時所在的對象 var _parice = $(bookItem).data("price"); var _book = $(bookItem).data("book"); this.data.books += _book + ","; this.data.price += parseInt(_parice); this.show(); $(".bg,.popupbox").hide(); }); }, }
在普通的click函數中 this 指向對象 $(".ok") ,所以,咱們若是想要獲取定義的對象中的數據(obj.data),那咱們只能在 click 方法前,就去用一個 that 自定義變量來保存這個 this ,
可是在箭頭函數中就不同了,this 始終指向定義函數時所在的對象(就是 obj 對象);
是否是更方便些!
在Vue中,也常用 vue實例,或者this來獲取相應的值
var vm = new Vue({ el:'#root', data:{ tasks:[] }, mounted(){ axios.get('/tasks') .then(function (response) { vm.tasks = response.data;//使用Vue實例 }) }, mounted2(){ axios.get('/tasks') .then(response => this.tasks = response.data);//箭頭函數 this } });
一、 在ES6中,能夠像C#那樣定義默認參數
function buyBook(price, count = 0.9){ return price * count; } buyBook(100); //甚至能夠將方法的值賦給參數 function buyBook(price, count =GetCount()){ return price * count; } function GetCount(){ return 100; } buyBook(200);
二、不只如此,還能夠快速獲取參數值
//ES6以前是這樣的 function add(a,b,c){ let total = a + b + c; return total; } add(1, 2, 3); //ES6你能夠這麼操做,提供了 rest 參數來訪問多餘變量 function sum(...num) { let total = 0; for (let i = 0; i < num.length; i++) { total = total + num[i]; } return total; } sum(1, 2, 3, 4, 6);
一、字符串表達式
在以前咱們都是這樣使用字符串表達式
var name = 'id is ' + bid+ ' ' + aid + '.' var url = 'http://localhost:5000/api/values/' + id
在ES6中咱們有了新語法,在反引號包裹的字符串中,使用${NAME}語法來表示模板字符:
var name = `id is ${aid} ${bid}` var url = `http://localhost:5000/api/values/${id}`//注意是反引號,英文輸入下下的,Tab鍵上邊的那個
二、還有就是多行表達式的寫法
//以前咱們都是這麼寫的 var roadPoem = '這個是一個段落' + '換了一行' + '增長了些內容' + 'dddddddddd' //可是在ES6中,可使用反引號 var roadPoem = `這個是一個段落 換了一行 增長了些內容, dddddddddd 結尾,`
一、什麼是模塊化開發
模塊化開發是基於必定的語法規範,經過代碼書寫設計,使代碼耦合度下降,模塊化的意義在於最大化的設計重用,以最少的模塊、零部件,更快速的知足更多的個性化需求。由於有了模塊,咱們就能夠更方便地使用別人的代碼,想要什麼功能,就加載什麼模塊。
用阮一峯大神的說法就是:
今天的Web網頁愈來愈像桌面程序,網頁上加載的javascript也愈來愈複雜,前端工程師不得不開始用軟件工程的思惟去管理本身的代碼。Javascript模塊化編程,已經成爲一個很是迫切的需求。理想狀況下,開發者只須要實現核心的業務邏輯,其餘均可以加載別人已經寫好的模塊。可是,Javascript不是一種模塊化編程語言,它不支持"類"(class),更別提"模塊"(module)了。(正在制定中的ECMAScript標準第六版將正式支持"類"和"模塊",但還須要很長時間才能投入使用
就這樣,Node.js 就出現了,一個用來開發服務器端的js框架,基於commonJs的模塊化。固然中間還有CMD,AMD(這個東西我還須要慢慢研究下);
二、模塊化在代碼中是如何體現的呢
一、首先咱們先看看普通的定義一個類是如何寫的
新建一個index.js 文件
class Student { constructor(homework= []) { this.homework= homework; } study() { console.log(this.homework); } } const st = new Student ([ 'blog', 'api', 'vue' ]); st.study();
而後新建一個index.html頁面,引用該js文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src="index.js"></script> </body> </html>
而後就能夠獲得結果:
這是一個很簡單的,定義一個Student 類,而後定義一個方法,經過傳遞一個數組參數,來實例化。
這樣雖然很簡單,可是卻沒法複用,沒法做爲一個零件來使用。並且若是有一個地方要修改,多處都須要修改,這個面向對象的思想,沒有發揮出來;
這個時候你可能會說,把這個拆成兩個問題,就能夠複用了,嗯~試試
二、咱們把這兩個文件分開
新建一個Student.js ,定義處理Student類;而後新建一個main.js方法,來調用實例化該類,就可使用
而後在 index.html 頁面裏去引用這兩個文件
<body> <script src="Student.js"></script> <script src="main.js"></script> </body>
固然結果是同樣的,這樣雖然實現了分隔開,也能夠去不一樣的地方調用;
可是,從上文中你也看的出,若是不是本身寫的代碼,通常不太容易看的明白,究竟是什麼意思,直觀性不是很好,咱們將沒法看到彼此間的關聯(main.js 加載 Student.js),
三、咱們用模塊的寫法設計這個調用
ES6 模塊不是對象,而是經過export
命令顯式指定輸出的代碼,再經過import
命令輸入。
咱們直接修改以前的代碼
而後在 index.html 頁面中,只須要引用 <script src="main.js"></script> 就行
四、由於瀏覽器如今還不能直接運行模塊化代碼,因此咱們須要打包,打包工具備不少,好比 webpack
注意:這裏用到打包概念,以後會講到,這裏就先略過,之後會講到,步驟是
首先安裝npm,或者阿里鏡像 cnpm(npm實際上是Node.js的包管理工具,這個在咱們以後的Node.js環境配置中,自動隨帶安裝)
全局安裝 rollup.js $ cnpm install --global rollupcd 當前文件夾 $ rollup main.js --format iife --output bundle.js
而後只須要引用生成的 <script src="bundle.js"></script>
五、這裏我由於測試,已經生成好了,打包出來的bundle.js 是這樣的,是否是兜兜轉轉又回到了以前的寫法,其實ES6的模塊開發,就是導入的代碼塊兒
(function () { 'use strict'; class TaskCollection { constructor(tasks = []) { this.tasks = tasks; } dump() { console.log(this.tasks); } } const tc = new TaskCollection([ 'blog', 'api', 'vue' ]); tc.dump(); }());
總結來講:模塊化的好處和問題
可維護性
靈活架構,焦點分離
方便模塊間組合、分解
方便單個模塊功能調試、升級
多人協做互不干擾
可測試性,可分單元測試;
性能損耗
系統分層,調用鏈會很長
模塊間通訊,模塊間發送消息會很耗性能
其實說白了,就是JS在做爲一個開發語言來講,愈來愈靠近了後端服務器語言。
這裏是一個特別特別簡單的關於ES6的留言板,你們能夠看一看
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2>簡易留言板</h2> <input type="text" placeholder="請輸入內容" size="30" id="msg"> <input type="button" value="留言" id="btn"> <div id="msg-div"></div> <script> //let 定義塊級變量 let oBtn = document.getElementById('btn'); let msg = document.getElementById('msg'); let content = document.getElementById('msg-div'); oBtn.onclick = () => { let ovalue = msg.value; let ali = document.createElement('p'); //ES6模板字符串 //多行表達式 ali.innerHTML = `${ovalue}<span style="color:red;"> 刪除</span>`; var aspan = content.getElementsByTagName('p'); if (aspan.length > 0) { content.insertBefore(ali, aspan[0]); } else { content.appendChild(ali); } msg.value = ''; var oSpan = content.getElementsByTagName('span'); for (let i = 0; i < oSpan.length; i++) { //ES6箭頭函數 oSpan[i].onclick = function () { content.removeChild(this.parentNode);//注意this的指向 }; } }; </script> </body> </html>
經過這兩天的學習,你們瞭解到了,JS的一些特性和變化:嵌套字面量的定義,面向對象的封裝,類和模塊化的使用,ES6的日益成熟,經過打包進行發佈等等,都能表現出JS在向一個服務器端語言快速邁進的衝動,也是極大的推進了,MVVM的到來,從而實現像Node.js 這種,能夠脫離瀏覽器環境也能運行的不同視角。好啦,關於JS高階,這兩講已經差很少了,固然還有其餘的,你們能夠自行學習瞭解,其實這兩篇都懂的化,已經差很少了,明天我們就開始正式進入Vue入門篇,經過引用Vue.js 實現栗子。