摘要:采用二八定律,主要涉及常用且重要的部分。對象是當前模塊的導出對象,用于導出模塊公有方法和屬性。箭頭函數函數箭頭函數把去掉,在與之間加上當我們使用箭頭函數時,函數體內的對象,就是定義時所在的對象,而不是使用時所在的對象。
ES6
原文博客地址:https://finget.github.io/2018/05/10/javascript-es6/
現在基本上開發中都在使用ES6,瀏覽器環境支持不好,可以用babel插件來解決。
采用‘二八定律’,主要涉及ES6常用且重要的部分。
問題:ES6模塊化如何使用,開發環境如何打包
Class和普通構造函數有何區別
Promise的基本使用和原理
總結一下ES6其他常用功能
ES6模塊化如何使用,開發環境如何打包 模塊化的基本語法// util1.js export default { a : 100 } const str = "hello"; export default str; // export default const str = "hello"; X
// util2.js export function fn1() { console.log("fn1"); } export function fn2() { console.log("fn2"); } export const fn3 = ()=> { console.log("fn3"); }
// index.js import str from "./util1.js"; import {fn1 , fn2} from "./util2.js"; import * as fn from "./util2.js"; console.log(str); fn1(); fn2(); fn.fn1(); fn.fn2();
export default 默認輸出這個,然后在import的時候就會拿到默認輸出的內容。例子中默認輸出的a=100。
export多個內容,在import時需要使用{}進行引用你需要的內容。
require: node 和 es6 都支持的引入
export / import : 只有es6 支持的導出引入
module.exports / exports: 只有 node 支持的導出
module.exports 初始值為一個空對象 {}
exports 是指向的 module.exports 的引用
require() 返回的是 module.exports 而不是 exports
Node里面的模塊系統遵循的是CommonJS規范。
CommonJS定義的模塊分為: 模塊標識(module)、模塊定義(exports) 、模塊引用(require)
在nodejs,exports 是 module.exports的引用,初始化時,它們都指向同一個{}對象。
對象在JS中屬于引用類型,意思就是exports和module.exports是指向同一個內存地址的。
看下面的例子:
exports.fn = function(){ console.log("fn"); } // 這兩種情況的效果是一樣的,上面說了exports與`module.exports初始化同一個對象,所以兩種定義方就是給這個同對象定義了一個fn的屬性,該屬性值為一個函數。 module.exports.fn = function(){ console.log("fn"); }
exports = function(){ console.log("fn"); } // 這兩種情況就不一樣了。上面的exports想當于指向了另一個內存地址。而下面這種情況是可以正常導出的。 module.exports = function(){ console.log("fn"); }
exports對象是當前模塊的導出對象,用于導出模塊公有方法和屬性。別的模塊通過require函數使用當前模塊時得到的就是當前模塊的exports對象。
module.exports 的使用
// sayHello.js function sayHello() { console.log("hello"); } module.exports = sayHello; // app.js var sayHello = require("./sayHello"); sayHello();
定義一個sayHello模塊,模塊里定義了一個sayHello方法,通過替換當前模塊exports對象的方式將sayHello方法導出。
在app.js中加載這個模塊,得到的是一個函數,調用該函數,控制臺打印hello。
// sayWorld.js module.exports = function(){ console.log("world"); } // app.js var sayWorld = require("./sayWorld"); // 匿名替換 sayWorld();
exports 導出多個變量
當要導出多個變量怎么辦呢?這個時候替換當前模塊對象的方法就不實用了,我們需要用到exports對象。
// userExports.js exports.a = function () { console.log("a exports"); } exports.b = function () { console.log("b exports"); } // app.js var useExports = require("./userExports"); useExports.a(); useExports.b(); // a exports // b exports
當然,將useExports.js改成這樣也是可以的:
// userExports.js module.exports.a = function () { console.log("a exports"); } module.exports.b = function () { console.log("b exports"); }
在實際開發當中可以只使用module.exports避免造成不必要的問題。開發環境配置
Babel中文網
nodejs環境 npm init
npm i babel-core babel-preset-es2015 babel-preset-latest --save-dev
創建.babelrc文件
npm i --global babel-cli
// .babelrc { "presets": ["es2015","latest"], "plugins": [] }
四大維度解鎖webpack3筆記
Rollup.js官網
npm init
安裝 rollup.js需要的一些插件
npm i rollup rollup-plugin-node-resolve rollup-plugin-babel babel-core babel-plugin-external-helpers babel-preset-latest --save-dev
配置 .babelrc
配置 rollup.config.js
rollup 功能單一(打包js模塊化), webpack功能強大
工具盡量功能單一,可繼承,可擴展
// .babelrc { "presets":[ ["latest", { "es2015":{ "modules": false } }] ], "plugins":["external-helpers"] }
// rollup.config.js import babel from "rollup-plugin-babel"; import resolve from "rollup-plugin-node-resolve"; export default { entry: "src/index.js", format: "umd", plugins: [ resolve(), babel({ exclude: "node_modules/**" }) ], dest: "build/bundle.js" }
// package.json ... "scripts":{ "start": "rollup -c rollup.config.js" } ...
npm run start
關于JS眾多模塊化標準沒有模塊化
AMD成為標準,require.js
前端打包工具,使得nodejs模塊化(CommonJS)可以被使用
ES6出現,想統一現在所有模塊化標準
nodejs積極支持,瀏覽器尚未統一
你可以自造lib,但是不要自造標準!!!
Class和普通構造函數有何區別 JS構造函數// 構造函數 function MathHandle(x, y){ this.x = x; this.y = y; } // 原型擴展 MathHandle.prototype.add = function(){ return this.x + this.y; } // 創建實例 var m = new ManthHandle(1,2); console.log(m.add()); // 3Class基本語法
class MathHandle { // 直接跟大括號 constructor(x, y) { this.x = x; this.y = y; } add() { return this.x + this.y; } } const m = new ManthHandle(1,2); console.log(m.add()); // 3語法糖
typeof MathHandle = "function"繼承 原生js繼承
MathHandle其實是個function,‘構造函數’
MathHandle === MathHandle.prototype.constructor
// 動物 function Animal() { this.eat = function() { console.log("animal eat"); } } // 狗 function Dog() { this.bark = function(){ console.log("dog bark"); } } // 綁定原型,實現繼承 Dog.prototype = new Animal(); // 實例化一只狗 var hashiqi = new Dog(); // hashiqi就有了eat方法 hashiqi.eat(); // animal eat
廖雪峰老師的原型繼承:點這里ES6繼承
class Animal { constructor(name){ this.name = name; } eat() { console.log(`${this.name} eat`); } } class Dog extends Animal { // extends 繼承 constructor(name){ super(name); // 必須* 記得用super調用父類的構造方法! this.name = name; } say() { console.log(`${this.name} say`); } } const dog = new Dog("hashiqi"); dog.eat(); // hashiqi eatPromise 的基礎使用
解決回調地獄(Callback Hell)Promise 基礎語法
詳細點的Promise:點這里
new Promise((resolve, reject) => { // 一段耗時很長的異步操作 ..... resolve(); // 數據處理完成 reject(); // 數據處理出錯 }).then(function A() { // 成功,下一步 }, function B(){ // 失敗,做相應處理 })
我最開始接觸到Promise的時候,一直傻了吧唧的在想resolve()和reject()在什么時候調用。resolve和reject
resolve()和reject()就是為后面then()中的兩個函數服務的。
new Promise((resolve, reject) => { setTimeout(()=>{ resolve("good,我要傳給then里的一個函數"); },2000); setTimeout(()=>{ reject("錯了,把我給我then里的第二個函數"); },2000); }).then(value => { console.log(value); // good,我要傳給then里的一個函數 },value => { console.log(value); // 錯了,把我給我then里的第二個函數 });來個實際的例子
/** * 基于jquery封裝一個promise ajax請求 * @param {[type]} param [選項] * @return {[type]} [description] */ request(param){ return new Promise((resolve,reject) => { $.ajax({ type : param.type || "get", url : param.url || "", dataType : param.dataType || "json", data : param.data || null, success:(res)=>{ // 用箭頭函數避免this指向問題 if (0 === res.status) { typeof resolve === "function"&&resolve(res.data, res.msg); // 成功就把請求到的數據用resolve返回,這樣就可以在then的第一個函數里拿到值了 } else { typeof reject === "function"&&reject(res.msg || res.data); // 失敗就返回錯誤信息 } }, error:(err)=>{ // 這個失敗是請求失敗,上面那個失敗是請求成功發送了,但是沒有拿到數據失敗了 typeof reject === "function"&&reject(err.statusText); } }) }) }ES6常用其他功能 let/const
let const與var都是用來定義變量的,不同的是let自帶作用域,const不能重復賦值。
let name = "FinGet" while (true) { let name = "GetFin" console.log(name) //GetFin break } console.log(name) //FinGet
let定義的變量只在包含它的代碼塊內有用
const PI = 3.1415926; PI = 3.14; // 錯誤多行字符串/模板變量
let name = "FinGet"; let age = 22; // js var str = "我是"+ name+",今年"+age+"歲"; // 很麻煩 let str1 = `我是${name},今年${age}歲`; // 簡單多了
模板字符串就是用`(Tab鍵上面那個)包含,變量就是用${}`表示解構賦值
let obj = { name: "FinGet", age: 22, job: "前端", addr: "成都" } let {name,age} = obj; console.log(name); // FinGet console.log(age); // 22
還可以反過來:
let name = "FinGet"; let age = 22; let job = "前端"; let addr = "成都"; let obj = {name,age,job,addr}; //obj = {name: "FinGet",age: 22,job: "前端",addr: "成都"}塊級作用域
另外一個var帶來的不合理場景就是用來計數的循環變量泄露為全局變量,看下面的例子:
// js var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
let 自帶塊級作用域
// ES6 var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
原生js想實現這種效果,需要用到閉包:
var a = []; for (var i = 0; i < 10; i++) { (function(j){ // 立即執行函數 a[j] = function() { console.log(j); } }(i)) } a[6](); // 6
立即執行函數形成了一個塊級作用域,將參數j保存了下來,并不會被‘污染’,原生js沒有塊級作用域,var在for中定義的變量是個全局變量,可以在外部訪問,也就可以被改變,所以每次for循環都是重置修改i的值,導致最后只能輸出10。函數默認參數與rest
default很簡單,意思就是默認值。大家可以看下面的例子,調用animal()方法時忘了傳參數,傳統的做法就是加上這一句type = type || "cat" 來指定默認值。
function animal(type){ type = type || "cat" console.log(type) } animal()
如果用ES6我們而已直接這么寫:
function animal(type = "cat"){ console.log(type) } animal(); // cat
最后一個rest語法也很簡單,直接看例子:
function animals(...types){ console.log(types) } animals("cat", "dog", "fish") //["cat", "dog", "fish"]
而如果不用ES6的話,我們則得使用ES5的arguments。箭頭函數
// js函數 function (a,b){ console.log(a+b); }
// es6箭頭函數 (a,b) => { console.log(a+b); }
把function去掉,在()與{}之間加上=>
當我們使用箭頭函數時,函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。最后
并不是因為箭頭函數內部有綁定this的機制,實際原因是箭頭函數根本沒有自己的this,它的this是繼承外面的,因此內部的this就是外層代碼塊的this。
創建了一個前端學習交流群,感興趣的朋友,一起來嗨呀!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99490.html
摘要:之所以是單線程,取決于它的實際使用,例如不可能同添加一個和刪除這個,所以它只能是單線程的。所以,這個新標準并沒有改變單線程的本質。 原文博客地址:https://finget.github.io/2018/05/21/async/ 異步 什么是單線程,和異步有什么關系 什么是event-loop 是否用過jQuery的Deferred Promise的基本使用和原理 介紹一下asyn...
摘要:原文博客地址另一篇轉載的從初級往高級走系列原型定義原型是對象的一個屬性,它定義了構造函數制造出的對象的公共祖先。 原文博客地址:https://finget.github.io/2018/09/13/proto/另一篇轉載的JavaScript從初級往高級走系列————prototype 原型 定義: 原型是function對象的一個屬性,它定義了構造函數制造出的對象的公共祖先。通...
摘要:原文博客地址如何理解如何實現是否解讀過的源碼與框架的區別實現實現獨立初始化實例兩者的區別數據和視圖的分離,解耦開放封閉原則,對擴展開放,對修改封閉在中在代碼中操作視圖和數據,混在一塊了以數據驅動視圖,只關心數據變化, 原文博客地址:https://finget.github.io/2018/05/31/mvvm-vue/ MVVM 如何理解 MVVM 如何實現 MVVM 是否解讀過 ...
摘要:當中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響布局的,比如。則就叫稱為重繪。 原文博客地址:https://finget.github.io/2018/05/22/virtualDom/ 什么是虛擬DOM 用JS模擬DOM結構 DOM變化的對比,放在JS層來做(圖靈完備語言) 提高重繪性能 重繪和回流 頁面渲染過程:showImg(https://seg...
摘要:模塊化是隨著前端技術的發展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調也不等同于異步。將會討論安全的類型檢測惰性載入函數凍結對象定時器等話題。 Vue.js 前后端同構方案之準備篇——代碼優化 目前 Vue.js 的火爆不亞于當初的 React,本人對寫代碼有潔癖,代碼也是藝術。此篇是準備篇,工欲善其事,必先利其器。我們先在代...
閱讀 1974·2021-11-22 19:20
閱讀 2618·2021-11-22 13:54
閱讀 1932·2021-09-04 16:40
閱讀 1814·2021-08-13 11:54
閱讀 2628·2019-08-30 15:55
閱讀 3456·2019-08-29 13:51
閱讀 519·2019-08-29 11:09
閱讀 2997·2019-08-26 14:06