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

資訊專欄INFORMATION COLUMN

ES6 —項目綜合實戰(zhàn)(完結(jié)篇)

izhuhaodev / 2884人閱讀

摘要:模塊化以項目中普遍會有的文件為例,實現(xiàn)導(dǎo)出再在其他文件中通過實現(xiàn)導(dǎo)入導(dǎo)入模塊使用統(tǒng)一的模塊化規(guī)范,可以提高代碼的可讀性,更易于維護。類操作先實戰(zhàn)創(chuàng)建一個類在中創(chuàng)建實例中的類能讓我們可以用更簡明的語法實現(xiàn)繼承,也使代碼的可讀性變得更高。

上一篇通過TodoList的練習(xí),目的是為了讓大家理解ES6中各種新特性的實際用途。

最好的學(xué)習(xí)方法就是實踐,所以這節(jié)課結(jié)合實際項目,來更好的理解和掌握ES6的用途和使用場景,達到靈活運用的目的。

1、模塊化

以項目中普遍會有的config.js文件為例,實現(xiàn)export導(dǎo)出:

const githubURL = "OUR GITHUB URL HERE";
const staticServer = "http://xxx.com";
const testsPath = `zaz-${type}-${name}/tests/index.htm?zaz[env]=tests`;
const name = "stalker";
const type = "mod";
const version = "0.0.1";
const state = "ok";
const description = "JavaScript API to deal with user data";
let globalpkg = null; 
const config = {
  _static: {
  name,
  version,
  state,
  description,
  docs: `${githubURL}/pages/terra/zaz-${type}-${name}`,
  source: `${githubURL}/Terra/zaz-${type}-${name}`,
  tests: `${staticServer}/fe/${testsPath}`,
  dependencies: ["mod.wilson"]
  }
};
export default config;

再在其他文件中通過import實現(xiàn)導(dǎo)入:

import config from "./config";//導(dǎo)入ES6模塊
import { globalpkg } from "./config";
import factory from "./factory";

 zaz.use((pkg) => {
   "use strict";
    config.dynamic.globalpkg = pkg;
    pkg.require(["modFactory"], (modFactory) => {
        modFactory.create(pkg.utils.deepMerge(config._static, factory));
    });
 });

使用ES6統(tǒng)一的模塊化規(guī)范,可以提高代碼的可讀性,更易于維護。

2、數(shù)組操作

import React,{Component} from "react";
class RepeatArray extends Component{
  constructor() {
    super();
  }
  render(){
    const names = ["Alice", "Emily", "Kate"];
    return (
      
{ let p=document.querySelectorAll("p"); let pArr=Array.from(p); pArr.forEach(function(item){ console.log(item.textContent); }); Array.from(pArr,function(item){return item + "ES6"}); }
); } }

使用Array.from 同時對每個元素進行操作。

3、模板字符串

常見的使用場景便是寫組件模板時使用:

$("#result").append(`
   There are ${basket.count} items
    in your basket, ${basket.onSale}
   are on sale!
 `);

可以在模板字符串中任意的嵌入變量, 調(diào)用函數(shù)等。

4、解構(gòu)與擴展操作符

擴展操作符在父組件給子組件傳遞一批屬性的情境中更為方便。

下面的例子把className以外的所有屬性傳遞給div標簽

class AutoloadingPostsGrid extends React.Component {
    render() {
        var {
            className,
            ...others,  // contains all properties of this.props except for className
        } = this.props;
        return (
            
); } }

使用react開發(fā)最常見的問題就是父組件要傳給子組件的屬性較多時比較麻煩

class MyComponent extends React.Component{
//假設(shè)MyComponent已經(jīng)有了name和age屬性
  render(){
    return (
      
     )
  }
}

使用擴展操作符可以變得很簡單

class MyComponent extends React.Component{
//假設(shè)MyComponent已經(jīng)有了name和age屬性
  render(){
    return (
      
     )
  }
}

上述方式是將父組件的所有屬性都傳遞下去,如果這其中有些屬性不需要傳遞呢?也很簡單

class MyComponent extends React.Component{
//假設(shè)MyComponent有很多屬性,而name屬性不需要傳遞給子組件
  var {name,...MyProps}=this.props;
  render(){
    return (
      
     )
  }
}

上述方法最常用的場景就是父組件的class屬性需要被多帶帶提取出來作為某個元素的class,而其他屬性需要傳遞給子組件。

在構(gòu)建通用容器時,擴展屬性會非常有用。

function App1() {
  return ;
}

function App2() {
  const props = {firstName: "Ben", lastName: "Hector"};
  return ;
}


5、Promise

場景一 : 所有圖片加載完再顯示在頁面上,避免頁面閃動。

  function loadImg(src) {
    return new Promise((resolve, reject) => {
       let img = document.createElement("img");
       img.src = src;
       img.onload = function () {
         resolve(img)
       }
       img.onerror = function (err) {
         reject(err)
       }
    })
  }

  function showImgs(imgs) {
    imgs.forEach(function(img){
      document.body.appendChild(img);
    })
  }

  Promise.all([
    loadImg("https://example.com/pic1")
    loadImg("https://example.com/pic2")
    loadImg("https://example.com/pic3")
  ]).then(showImgs)


場景二: 多個資源中只要加載了其中一種就可。

{
  function loadImg(src) {
    return new Promise((resolve, reject) => {
       let img = document.createElement("img");
       img.src = src;
       img.onload = function () {
         resolve(img)
       }
       img.onerror = function (err) {
         reject(err)
       }
    })
  }

  function showImgs(img) {
    document.body.appendChild(img);
  }

  Promise.race([
    loadImg("https://example.com/pic1")
    loadImg("https://example.com/pic2")
    loadImg("https://example.com/pic3")
  ]).then(showImgs)
}


6、Generator

在異步編程的解決方案中,Generator比Promise更高級些。

使用場景:抽獎次數(shù)邏輯控制、長輪詢(服務(wù)器請求報錯再次請求, 定時發(fā)送請求)

  // 以前控制次數(shù)是在全局中申明,既不安全又影響性能
  let draw = function (count) {
    // 具體抽獎邏輯
    console.info(`剩余${count}次`)
  }

  let residue = function* (count) {
    while (count > 0) {
      count--
      yield draw(count)
    }
  }

  let start = residue(5)
  let btn = document.createElement("button")
  btn.id="start"
  btn.textContent = "抽獎"
  document.body.appendChild(btn);
  document.getElementById("start").addEventListener("click", function() {
    start.next()
  }, false)
}
{
  // 長輪詢
  let ajax = function* () {
    yield new Promise(function(resolve, reject) {
      setTimeout(() => {
        resolve({code: 0})
      }, 200);
    })
  }

  let pull = function () {
    let generator = ajax()
    let step = generator.next()
    step.value.then(function(d){
      if (d.code !=0 ) {
        setTimeout(() => {
          console.info("wait")
          pull()
        }, 100);
      } else {
        console.info(d)
      }
    })
  }

  pull()

通過下面這張流程圖,再加深下對Generator的理解。

7、await

在項目中,有時會出現(xiàn)需要同時依賴多個接口,而且必須在這幾個請求都處理完后,才能開始處理數(shù)據(jù)的情況。我們可以在一個 async函數(shù) 中寫多個await 語法的請求,然后逐個處理,但是這樣效率太低了。

多個請求是可以并行執(zhí)行的。這時就可以結(jié)合 Promise.all 高級方法來處理,可以同時發(fā)起多個請求,然后統(tǒng)一處理接口返回數(shù)據(jù)。

為了方便,這里演示同時請求2個url,多個的也是一樣的, 如下:

export default {
  name: "hello1",
  data () {
    return {
      msg: "Hello Vue.js",
      info: {},
      user1: {},
      user2: {}
    }
  },
  methods: {
    async getUserInfo () {
      try {
        const res = await this.$http.get("http://aaa.com/userinfo");
        this.info = res.data
      } catch (e) {
        console.log(e);
      }
    },
    async get2UserInfo () {
      try {
        const res = await Promise.all([
          this.$http.get("http://aaa.com/userinfo1"),
          this.$http.get("http://aaa.com/userinfo2"),
        ])
        this.user1 = res[0].data;
        this.user2 = res[1].data;
      } catch (e) {
        console.log(e);
      }
    }
  },
  created () {
    this.getUserInfo();
    this.get2UserInfo();
  }
}

再次運行項目,可以發(fā)現(xiàn)頁面在初始化的時候同時發(fā)起了3個請求,并正常渲染出了接口數(shù)據(jù)。

注意:這里的 Promise.all() 的參數(shù)是一個函數(shù)執(zhí)行隊列,它們會同時發(fā)起,然后都請求成功后,會將隊列的每個任務(wù)的結(jié)果組裝成一個結(jié)果數(shù)據(jù),然后返回。


8、類操作

先實戰(zhàn)創(chuàng)建一個List類

import Utils from "./Utils.js";
class List {
    constructor(title = "", items = [], isEditable = true, id = "") {
        this.id = (id) ? id : Utils.guid();
        this.title = title;
        this.items = items;
        this.isEditable = isEditable;
    }
    render() {
        var html = `

${this.title}

${(this.isEditable) ? "
X
" : ""}
    `; this.items.forEach(function(item) { html += item.render(); }); html += `
${(this.isEditable) ? "
Add Item
" : ""}
`; return html; } getItemById(id) { let item = this.items.filter(i => i.id === id); return ((item.length) ? item[0] : null); } add(item) { this.items.push(item); } remove(item) { this.items = this.items.filter(i => (i.id !== item.id)); } } export default List;

在app.js中創(chuàng)建List實例:

import List from "./List.js";
import Utils from "./Utils.js";
import Status from "./Status.js";
class App {
    constructor(lists = []) {
        this.lists = lists;
    }
    getDueItems() {
        let dueItems = [];
        this.lists.forEach(function(list) {
            list.items.forEach(function(item) {
                if (item.date && item.status === Status.PENDING && Utils.dateDiffInDays(new Date(item.date), new Date()) > 0) {
                    dueItems.push(item);
                }
            });
        });
        return dueItems;
    }
    getItemById(id) {
        const filterById = (function filterById(id1) {
            return function(listItem) {
                return listItem.id === id1;
            };
        }(id));
        for (let i = 0; i < this.lists.length; i++) {
            let item = this.lists[i].items.filter(filterById);
            if (item.length) {
                return item[0];
            }
        }
        return null;
    }
    getListById(id) {
        let list = this.lists.filter(l => l.id === id);
        return ((list.length) ? list[0] : null);
    }
    render() {
        let pastDueList = new List("Past Due Date", this.getDueItems(), false);
        let html = `
[+] Add List
`; this.lists.forEach(function(list) { html += list.render(); }); html += pastDueList.render(); html += "
"; return html; } add(list) { this.lists.push(list); } remove(list) { this.lists = this.lists.filter(l => (l.id !== list.id)); } } export default App;

ES6中的類能讓我們可以用更簡明的語法實現(xiàn)繼承,也使代碼的可讀性變得更高。

9、Proxy

Proxy可以讓我們根據(jù)不同的業(yè)務(wù)邏輯進行相應(yīng)的處理, 對原對象進行映射,生成新的對象,操作新對象的同時通過一定的規(guī)則修改原對象。

  // 先定義一個函數(shù)
  function validator(target,validator) {
    return new Proxy(target, {
      _validator: validator,
      set(targer,key,value,proxy){
        if (targer.hasOwnProperty(key)) {
          let va = this._validator[key];
          if (!!va(value)) {
            return Reflect.set(target,key,value,proxy)
          }else {
            throw Error(`不能設(shè)置${key}到${value}`)
          }
        }else {
          throw Error(`${key} 不存在`)
        }
      }
    })
  }
  const personValidator={
    name(val){
      return typeof val === "string"
    },
    age(val){
      return typeof val === "number" && val >18
    }
  }

  class Person{
    constructor(name,age) {
      this.name = name
      this.age = age
      return validator(this, personValidator)
    }
  }

  const person  = new Person("lilei", 30)
  console.info(person) // Proxy {name: "lilei", age: 30}
  // person.name = 48 // Uncaught Error: 不能設(shè)置name到48
  // console.info(person)
  person.name = "han mei mei"
  console.info(person) // Proxy {name: "han mei mei", age: 30}

點評:使用Proxy進行數(shù)據(jù)校驗,將對象和驗證分離開,便于后期代碼的維護。

總結(jié)

本篇主要通過實際項目中的例子回顧ES6的知識點,幫大家梳理重點和難點。學(xué)會ES6語法不難,活學(xué)活用到項目才是關(guān)鍵。

希望各位小伙伴能充分認識到ES6的強大,通過在實際工作中不斷地使用ES6,提升代碼質(zhì)量和工作效率,這樣就能多一點喝茶看電影的時間。

最后祝大家都能成為別人眼中的程序猿大牛,O(∩_∩)O哈哈~

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

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

相關(guān)文章

  • 完結(jié)匯總】iKcamp出品基于Koa2搭建Node.js實戰(zhàn)共十一堂課(含視頻)

    摘要:云集一線大廠有真正實力的程序員團隊云集一線大廠經(jīng)驗豐厚的碼農(nóng),開源奉獻各教程。融合多種常見的需求場景網(wǎng)絡(luò)請求解析模板引擎靜態(tài)資源日志記錄錯誤請求處理。結(jié)合語句中轉(zhuǎn)中間件控制權(quán),解決回調(diào)地獄問題。注意分支中的目錄為當節(jié)課程后的完整代碼。 ?? ?與眾不同的學(xué)習(xí)方式,為你打開新的編程視角 獨特的『同步學(xué)習(xí)』方式 文案講解+視頻演示,文字可激發(fā)深層的思考、視頻可還原實戰(zhàn)操作過程。 云...

    sPeng 評論0 收藏0
  • JS筆記

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識之 HTTP 協(xié)議 詳細介紹 HTT...

    rottengeek 評論0 收藏0
  • 前端相關(guān)大雜燴

    摘要:希望幫助更多的前端愛好者學(xué)習(xí)。前端開發(fā)者指南作者科迪林黎,由前端大師傾情贊助。翻譯最佳實踐譯者張捷滬江前端開發(fā)工程師當你問起有關(guān)與時,老司機們首先就會告訴你其實是個沒有網(wǎng)絡(luò)請求功能的庫。 前端基礎(chǔ)面試題(JS部分) 前端基礎(chǔ)面試題(JS部分) 學(xué)習(xí) React.js 比你想象的要簡單 原文地址:Learning React.js is easier than you think 原文作...

    fuyi501 評論0 收藏0

發(fā)表評論

0條評論

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