成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript從初級往高級走系列————ES6

孫淑建 / 724人閱讀

摘要:采用二八定律,主要涉及常用且重要的部分。對象是當(dāng)前模塊的導(dǎo)出對象,用于導(dǎo)出模塊公有方法和屬性。箭頭函數(shù)函數(shù)箭頭函數(shù)把去掉,在與之間加上當(dāng)我們使用箭頭函數(shù)時,函數(shù)體內(nèi)的對象,就是定義時所在的對象,而不是使用時所在的對象。

ES6
原文博客地址:https://finget.github.io/2018/05/10/javascript-es6/
現(xiàn)在基本上開發(fā)中都在使用ES6,瀏覽器環(huán)境支持不好,可以用babel插件來解決。

采用‘二八定律’,主要涉及ES6常用且重要的部分。

問題:

ES6模塊化如何使用,開發(fā)環(huán)境如何打包

Class和普通構(gòu)造函數(shù)有何區(qū)別

Promise的基本使用和原理

總結(jié)一下ES6其他常用功能

ES6模塊化如何使用,開發(fā)環(huán)境如何打包 模塊化的基本語法
// 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 默認(rèn)輸出這個,然后在import的時候就會拿到默認(rèn)輸出的內(nèi)容。例子中默認(rèn)輸出的a=100。
export多個內(nèi)容,在import時需要使用{}進(jìn)行引用你需要的內(nèi)容。
exportexport defaultexportsmodule.exports的區(qū)別
require: node 和 es6 都支持的引入
export / import : 只有es6 支持的導(dǎo)出引入
module.exports / exports: 只有 node 支持的導(dǎo)出

module.exports 初始值為一個空對象 {}

exports 是指向的 module.exports 的引用

require() 返回的是 module.exports 而不是 exports

Node里面的模塊系統(tǒng)遵循的是CommonJS規(guī)范。

CommonJS定義的模塊分為: 模塊標(biāo)識(module)、模塊定義(exports) 、模塊引用(require)

在nodejs,exportsmodule.exports的引用,初始化時,它們都指向同一個{}對象。

對象在JS中屬于引用類型,意思就是exportsmodule.exports是指向同一個內(nèi)存地址的。

看下面的例子:

exports.fn = function(){
  console.log("fn");
}
// 這兩種情況的效果是一樣的,上面說了exports與`module.exports初始化同一個對象,所以兩種定義方就是給這個同對象定義了一個fn的屬性,該屬性值為一個函數(shù)。
module.exports.fn = function(){
  console.log("fn");
}
exports = function(){
  console.log("fn");
}
// 這兩種情況就不一樣了。上面的exports想當(dāng)于指向了另一個內(nèi)存地址。而下面這種情況是可以正常導(dǎo)出的。
module.exports = function(){
  console.log("fn");
}
exports對象是當(dāng)前模塊的導(dǎo)出對象,用于導(dǎo)出模塊公有方法和屬性。別的模塊通過require函數(shù)使用當(dāng)前模塊時得到的就是當(dāng)前模塊的exports對象。

module.exports 的使用

// sayHello.js

function sayHello() {
  console.log("hello");
}

module.exports = sayHello;

// app.js
var sayHello = require("./sayHello");

sayHello();

定義一個sayHello模塊,模塊里定義了一個sayHello方法,通過替換當(dāng)前模塊exports對象的方式將sayHello方法導(dǎo)出。
在app.js中加載這個模塊,得到的是一個函數(shù),調(diào)用該函數(shù),控制臺打印hello。

// sayWorld.js
module.exports = function(){
  console.log("world");
}
// app.js
var sayWorld = require("./sayWorld"); // 匿名替換
sayWorld();

exports 導(dǎo)出多個變量

當(dāng)要導(dǎo)出多個變量怎么辦呢?這個時候替換當(dāng)前模塊對象的方法就不實用了,我們需要用到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

當(dāng)然,將useExports.js改成這樣也是可以的:

// userExports.js
module.exports.a = function () {
  console.log("a exports");
}
 
module.exports.b = function () {
  console.log("b exports");
}
在實際開發(fā)當(dāng)中可以只使用module.exports避免造成不必要的問題。
開發(fā)環(huán)境配置
babel

Babel中文網(wǎng)

nodejs環(huán)境 npm init

npm i babel-core babel-preset-es2015 babel-preset-latest --save-dev

創(chuàng)建.babelrc文件

npm i --global babel-cli

// .babelrc
{
  "presets": ["es2015","latest"],
  "plugins": []
}
webpack

四大維度解鎖webpack3筆記

rollup.js

Rollup.js官網(wǎng)

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功能強(qiáng)大
工具盡量功能單一,可繼承,可擴(kuò)展
// .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

關(guān)于JS眾多模塊化標(biāo)準(zhǔn)

沒有模塊化

AMD成為標(biāo)準(zhǔn),require.js

前端打包工具,使得nodejs模塊化(CommonJS)可以被使用

ES6出現(xiàn),想統(tǒng)一現(xiàn)在所有模塊化標(biāo)準(zhǔn)

nodejs積極支持,瀏覽器尚未統(tǒng)一

你可以自造lib,但是不要自造標(biāo)準(zhǔn)?。?!

Class和普通構(gòu)造函數(shù)有何區(qū)別 JS構(gòu)造函數(shù)
// 構(gòu)造函數(shù)
function MathHandle(x, y){
  this.x = x;
  this.y = y;
}
// 原型擴(kuò)展
MathHandle.prototype.add = function(){
  return this.x + this.y;
}

// 創(chuàng)建實例
var m = new ManthHandle(1,2);
console.log(m.add()); // 3
Class基本語法
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"
MathHandle其實是個function,‘構(gòu)造函數(shù)’
MathHandle === MathHandle.prototype.constructor
繼承 原生js繼承
// 動物
function Animal() {
  this.eat = function() {
    console.log("animal eat");
  }
}
// 狗
function Dog() {
  this.bark = function(){
    console.log("dog bark");
  }
}
// 綁定原型,實現(xiàn)繼承
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調(diào)用父類的構(gòu)造方法!
    this.name = name;
  }
  say() {
    console.log(`${this.name} say`);
  }
}

const dog = new Dog("hashiqi");
dog.eat(); // hashiqi eat
Promise 的基礎(chǔ)使用
解決回調(diào)地獄(Callback Hell)
詳細(xì)點的Promise:點這里
Promise 基礎(chǔ)語法
new Promise((resolve, reject) => {
  // 一段耗時很長的異步操作
    .....
  resolve(); // 數(shù)據(jù)處理完成
  reject(); // 數(shù)據(jù)處理出錯
}).then(function A() {
  // 成功,下一步
}, function B(){
  // 失敗,做相應(yīng)處理
})
我最開始接觸到Promise的時候,一直傻了吧唧的在想resolve()reject()在什么時候調(diào)用。
resolve()reject()就是為后面then()中的兩個函數(shù)服務(wù)的。
resolve和reject
new Promise((resolve, reject) => {
  setTimeout(()=>{
    resolve("good,我要傳給then里的一個函數(shù)");
  },2000);
  setTimeout(()=>{
    reject("錯了,把我給我then里的第二個函數(shù)");
  },2000);
}).then(value => {
  console.log(value); // good,我要傳給then里的一個函數(shù)
},value => {
  console.log(value); // 錯了,把我給我then里的第二個函數(shù)
});
來個實際的例子
/**
 * 基于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)=>{ // 用箭頭函數(shù)避免this指向問題
        if (0 === res.status) {
           typeof resolve === "function"&&resolve(res.data, res.msg); // 成功就把請求到的數(shù)據(jù)用resolve返回,這樣就可以在then的第一個函數(shù)里拿到值了
        } else {
           typeof reject === "function"&&reject(res.msg || res.data); // 失敗就返回錯誤信息
        }

      },
      error:(err)=>{ // 這個失敗是請求失敗,上面那個失敗是請求成功發(fā)送了,但是沒有拿到數(shù)據(jù)失敗了
         typeof reject === "function"&&reject(err.statusText);
      }
    })
  })
}
ES6常用其他功能 let/const
let constvar都是用來定義變量的,不同的是let自帶作用域,const不能重復(fù)賦值。
let name = "FinGet"
while (true) {
    let name = "GetFin"
    console.log(name)  //GetFin
    break
}
console.log(name)  //FinGet
let定義的變量只在包含它的代碼塊內(nèi)有用
const PI = 3.1415926;
PI = 3.14; // 錯誤
多行字符串/模板變量
let name = "FinGet";
let age = 22;
// js
var str = "我是"+ name+",今年"+age+"歲"; // 很麻煩

let str1 = `我是${name},今年${age}歲`; // 簡單多了
模板字符串就是用`(Tab鍵上面那個)包含,變量就是用${}`表示
解構(gòu)賦值
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帶來的不合理場景就是用來計數(shù)的循環(huán)變量泄露為全局變量,看下面的例子:

// 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想實現(xiàn)這種效果,需要用到閉包:

var a = [];
for (var i = 0; i < 10; i++) {
  (function(j){ // 立即執(zhí)行函數(shù)
    a[j] = function() {
      console.log(j);
    }
  }(i))
}
a[6](); // 6
立即執(zhí)行函數(shù)形成了一個塊級作用域,將參數(shù)j保存了下來,并不會被‘污染’,原生js沒有塊級作用域,varfor中定義的變量是個全局變量,可以在外部訪問,也就可以被改變,所以每次for循環(huán)都是重置修改i的值,導(dǎo)致最后只能輸出10。
函數(shù)默認(rèn)參數(shù)與rest
default很簡單,意思就是默認(rèn)值。大家可以看下面的例子,調(diào)用animal()方法時忘了傳參數(shù),傳統(tǒng)的做法就是加上這一句type = type || "cat" 來指定默認(rèn)值。
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。
箭頭函數(shù)
// js函數(shù)
function (a,b){
  console.log(a+b);
}
// es6箭頭函數(shù)
(a,b) => {
  console.log(a+b);
}
function去掉,在(){}之間加上=>
當(dāng)我們使用箭頭函數(shù)時,函數(shù)體內(nèi)的this對象,就是定義時所在的對象,而不是使用時所在的對象。
并不是因為箭頭函數(shù)內(nèi)部有綁定this的機(jī)制,實際原因是箭頭函數(shù)根本沒有自己的this,它的this是繼承外面的,因此內(nèi)部的this就是外層代碼塊的this。
最后

創(chuàng)建了一個前端學(xué)習(xí)交流群,感興趣的朋友,一起來嗨呀!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/99490.html

相關(guān)文章

  • JavaScript初級高級系列————異步

    摘要:之所以是單線程,取決于它的實際使用,例如不可能同添加一個和刪除這個,所以它只能是單線程的。所以,這個新標(biāo)準(zhǔn)并沒有改變單線程的本質(zhì)。 原文博客地址:https://finget.github.io/2018/05/21/async/ 異步 什么是單線程,和異步有什么關(guān)系 什么是event-loop 是否用過jQuery的Deferred Promise的基本使用和原理 介紹一下asyn...

    andot 評論0 收藏0
  • JavaScript初級高級系列————prototype

    摘要:原文博客地址另一篇轉(zhuǎn)載的從初級往高級走系列原型定義原型是對象的一個屬性,它定義了構(gòu)造函數(shù)制造出的對象的公共祖先。 原文博客地址:https://finget.github.io/2018/09/13/proto/另一篇轉(zhuǎn)載的JavaScript從初級往高級走系列————prototype 原型 定義: 原型是function對象的一個屬性,它定義了構(gòu)造函數(shù)制造出的對象的公共祖先。通...

    SKYZACK 評論0 收藏0
  • JavaScript初級高級系列————MVVM-Vue

    摘要:原文博客地址如何理解如何實現(xiàn)是否解讀過的源碼與框架的區(qū)別實現(xiàn)實現(xiàn)獨立初始化實例兩者的區(qū)別數(shù)據(jù)和視圖的分離,解耦開放封閉原則,對擴(kuò)展開放,對修改封閉在中在代碼中操作視圖和數(shù)據(jù),混在一塊了以數(shù)據(jù)驅(qū)動視圖,只關(guān)心數(shù)據(jù)變化, 原文博客地址:https://finget.github.io/2018/05/31/mvvm-vue/ MVVM 如何理解 MVVM 如何實現(xiàn) MVVM 是否解讀過 ...

    codercao 評論0 收藏0
  • JavaScript初級高級系列————Virtual Dom

    摘要:當(dāng)中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風(fēng)格,而不會影響布局的,比如。則就叫稱為重繪。 原文博客地址:https://finget.github.io/2018/05/22/virtualDom/ 什么是虛擬DOM 用JS模擬DOM結(jié)構(gòu) DOM變化的對比,放在JS層來做(圖靈完備語言) 提高重繪性能 重繪和回流 頁面渲染過程:showImg(https://seg...

    tinyq 評論0 收藏0
  • javascript知識點

    摘要:模塊化是隨著前端技術(shù)的發(fā)展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調(diào)也不等同于異步。將會討論安全的類型檢測惰性載入函數(shù)凍結(jié)對象定時器等話題。 Vue.js 前后端同構(gòu)方案之準(zhǔn)備篇——代碼優(yōu)化 目前 Vue.js 的火爆不亞于當(dāng)初的 React,本人對寫代碼有潔癖,代碼也是藝術(shù)。此篇是準(zhǔn)備篇,工欲善其事,必先利其器。我們先在代...

    Karrdy 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<