ES6讀書筆記 | Node.js | *.js

1.ES6特性

1.1 import 和 require 區(qū)別

require是執(zhí)行函數(shù)然后賦值給左邊的過程, 無論 module.exports 賦值的是匿名函數(shù) | 函數(shù) | Object,require 都會把它直接獲取到 , 該函數(shù)沒有考慮 default

而import 是編譯時的解構(gòu)過程,必須放在文件開頭,
export不允許接匿名函數(shù),即禁止a = ()=>1 || {sth:sth}; export aexport function(){},可替換為 export {a}export function a(){},
它區(qū)分default 和非 default :

不同的export 對應(yīng)的 import 方式 結(jié)果
export default {a,b} import a from './xx' log : {a:a,b:b}
export {a}; export 券犁; import {a,b} from './xx' a,b 是兩個不同的變量, 解構(gòu)了
import * as a from './xx' { a: [Function: a],
b: [Function: b],
default:
{ a: [Function: a],
b: [Function: b] } }

require 輸出的是一個值的復(fù)制,而 import 輸出的是值的只讀引用,類似于Unix的符號鏈接,會隨著原始值變化

循環(huán)加載時二者的表現(xiàn)不同,require 模塊遇到循環(huán)加載時返回的時當(dāng)前已經(jīng)執(zhí)行的部分的值,而import 因?yàn)榉祷氐氖侵档囊?只要引用存在就能執(zhí)行.

1.2 正則表達(dá)式

/a+/yes6中新增加了y作為粘連(sticky)修飾符, 和 g 一樣都是全局匹配, 但 y 要求每次匹配都都從上一次匹配成功的緊挨著的位置開始

1.2.1 具名組匹配

var e = /(?<year>\d{4})-(?<month>\d{2})/
var a = e.exec('2019-01'))
console.log(a.groups) // { year:"2019", month:"01" }
//也可以解構(gòu)賦值
let { groups:{ year, month} } = a
//字符串替換時, 使用 $<組名> 來引用具名組
'2019-02'.replace(e, '$<month>-$<year>') // 02-2019
//正則表達(dá)式內(nèi)部引用具名組匹配, 下面兩個式子等價
; /(\w+)!(\1)/.exec('abc!abc') // ["abc!abc", "abc", "abc", index: 0, input: "abc!abc", groups: undefined]
; /(?<name>\w+)!(\k<name>)/.exec('abc!abc') //["abc!abc", "abc", "abc", index: 0, input: "abc!abc", groups: {…}]
//由上式可知, js 的正則可以匹配如上述的上下文相關(guān)文法了

node8不支持. 但 chrome 和 node10 已支持
實(shí)在有想法的人也可以用正則表達(dá)式匹配回文字符串, 但這樣匹配實(shí)質(zhì)上等于/(.)(.)(.)\3\2\1/, 也就是說對字符串長度有要求, 且可讀性較差, 不如str.split('').reverse().join('') === str

1.3 Math 數(shù)學(xué)運(yùn)算擴(kuò)展

  • 8**2 == 64 加入了指數(shù)運(yùn)算符
  • Math.sinh(x)等 加入了雙曲函數(shù)方法

1.4 特殊的條件表達(dá)式

Object.is 和 ===的區(qū)別:

+0 === -1 //true
NaN === NaN // false
typeof null === "object" // true

Object.is(+0,-0) // false
Object.is(NaN, NaN) // true

1.5 Symbol

  • Symbol 是 js 第7種數(shù)據(jù)類型, 它是一種類似于字符串的原始類型, 不是對象, 不能添加屬性.
  • Symbol的出發(fā)點(diǎn)是用于表示獨(dú)一無二的值, 常用在 Object 的 key 值. 因此Symbol('123') !== Symbol('123')
  • Symbol值不能和其它類型的值進(jìn)行運(yùn)算
  • Symbol值可以顯示轉(zhuǎn)化為字符串String(Symbol('1'))或布爾 Boolean(Symbol()) , 但不能轉(zhuǎn)化為數(shù)值
  • Symbol.for('foo')全局搜索以該字符串作為名稱的 Symbol 值, 反向的有Symbol.keyFor(sym)
  • Symbol.toStringTag , 這個屬性可以用于定制[object Object][object Array]中 object 后面的字符串

1.6 Set

  • Set 的創(chuàng)建 new Set([1,2,3]);new Set(1,2,3)不行,因?yàn)榈谝粋€參數(shù)必須部署了iterable接口
  • Set 的屬性: 數(shù)組的arr.length 而set 有set.size
  • Set 的方法:
    • add delete has clear forEach
    • map 和 filter
      let set = new Set([1,2,3])
      set = new Set([...set].map(x => x*2) //或 filter(x=>x%2==0)
      
  • Set 的應(yīng)用:
    • 數(shù)組去重
       let unique = [...new Set([1,2,2,3,3,4])] 
      
    • 集合求 并集
    let union = new Set([...a,...b])
    
    • 集合求 交集
    let intersect = new Set([...a]).filter(x=>b.has(x))
    
    • 集合求 差集
    let difference = new Set([...a]).filter(x=> !b.has(x))
    

1.8 Map

  • Map 構(gòu)造 new Map([ ['key','value'], ['key2','value'] ]) 要求輸入?yún)?shù)具有 Iterator 接口并且每個成員都是一個雙元素數(shù)組
  • Map 屬性 size
  • Map 方法 set get has delete clear forEach
  • Map 和 Set 都有的方法keys() values() entries(), 都返回遍歷器對象, 同時對 map 和 set 使用 Object.keys 不會得到想要的結(jié)果

1.8.1 WeakMap 典型應(yīng)用:為 DOM 注冊事件的 listener

let myWeakMap = new WeakMap()
let el = document.getElementById('logo')
myWeakMap.set(el, { timesClicked : 0 } )
el.onclick = function(){
  myWeakMap.get(el).timesClicked++
}

這樣的好處是當(dāng)該 DOM 被刪除時,對應(yīng)的計數(shù)器變量也能被釋放內(nèi)存

附: 主動觸發(fā)事件:

var click = new MouseEvent('click')
el.dispatchEvent(click)

1.9 Proxy

1.9.1 Proxy 可以攔截的操作

  • get ,set, has(攔截propKey in proxy的操作), deleteProperty(攔截 delete target[key])
  • ownKeys(只有 Object.keys()返回對象的可遍歷屬性,其它接口都返回全部屬性,包括:
    • Object.getOwnPropertyNames()
    • Object.getOwnPropertySymbols()
    • Reflect.ownKeys()
  • apply(target,object,args) 攔截函數(shù)調(diào)用操作,包括f(),f.call(o,...args),f.apply()
  • construct 攔截 new 操作

1.9.2 proxy和Object.defineProperties區(qū)別

  • proxy創(chuàng)建了一個新的對象
  • proxy對this的處理 在Proxy 代理的情況下,目標(biāo)對象內(nèi)部的 this 會指向 Proxy 代理
  • proxy支持的屬性更多
    答:后者定義get set writeable value enumerable configurable 而 Proxy 和后者的交集只有 get 和 set
  • proxy 定義 get 和 set 時的propKey可以是參數(shù), 而后者必須是一個指定的字符串, 參數(shù)也比較少(set : function (newValue) { })

1.9.3 Proxy應(yīng)用

  • P238 攔截數(shù)組讀取負(fù)數(shù)索引(defineProperty 無法實(shí)現(xiàn))
function proxyArray(target) {
  let handler = {
    get(target, propKey, receiver) {
      let index = Number(propKey);
      if (index < 0) {
        propKey = String(target.length + index);
      }
      return Reflect.get(target, propKey, receiver);
    },
    set(target,propKey,value){
      let index = Number(propKey);
      if (index < 0) {
        propKey = String(target.length + index);
      }
      return target[propKey] = value
    }
  };
 return new Proxy(target, handler);
}

let arr = proxyArray([1,2,3]);
arr[-1] // 3

1.10 Reflect 能否還原proxy或defineP的get和set廓潜?

答: 不能

1.11 Promise

1.11.1 Promise.all()

var p = Promise.all([p1,p2,p3]) 處理邏輯類似于&&運(yùn)算, 只有p1 p2 p3都變成 Fulfilled.
相對的,Promise.race()就類似于或運(yùn)算

1.12 Iterator

1.12.1 關(guān)鍵詞

it.next() // { value : '', done : false }
一般部署了 next 接口的對象就可以視作 Iterator
部署了[Symbol.iterator]接口的對象就可以被遍歷

1.12.2 Object.keys和values和Iterator有關(guān)嗎谎脯?for in呢蝠筑?說到底壕曼,哪些有關(guān)屈张,哪些無關(guān)溢十?

  • o[Symbol.iterator]有關(guān): [...o],for of,yield* [1,2],Array.from()
  • 原生[Symbol.iterator]有關(guān):
    o.keys(),o.values(),o.entries()
  • 無關(guān): for in,Object.keys(a),Object.values(a),Object.entries(a)

測試代碼

var a = [1,2,3]
a[Symbol.iterator] = ()=>{ return { next: ()=>{ return {value:1,done:Math.random()>0.3}} } }
[...a] // 可能為[], [1], [1,1]

1.12.3 實(shí)現(xiàn)類python的range函數(shù)

優(yōu)點(diǎn): 相對創(chuàng)建數(shù)組來說更節(jié)省內(nèi)存

  • 原生 Iterator 實(shí)現(xiàn) next 的方法:
function range(start,stop){
  var o = { value:start,stop:stop }
  o[Symbol.iterator] = function(){ 
    return {
      next:()=>{
        if(this.value < this.stop){ 
          return { done:false, value:this.value++ }
        }else { return { done:true } }
      }
    }
  }
  return o
}
for(let i of range(0,5)){
  console.log(i) // 0,1,2,3,4
}
  • 使用 Generator 的話更簡潔:
function range(start,stop){
  return {
    *[Symbol.iterator](){
      for(let i=start;i<stop;i++){ yield i }
    }
  }
}
//或
function *range(start,stop){
      for(let i=start;i<stop;i++){ yield i }
}
[...range(0,5)] //[0,1,2,3,4]

1.12.4 為 Object 添加類似 map 的遍歷接口

Object.prototype[Symbol.iterator] = function * () {
        for(let i in this){ 
            yield [i,this[i]] 
        }
}
var o = { 'Li': { age:23 }, 'Wang' : { age:24 } } ;
[...o].filter(x=>x[1].age<=23) // [['Li',{age:23}]]

1.13 Generator 和 Iterator 的關(guān)系

Generator 函數(shù)就是 Iterator 遍歷器生成函數(shù), Generator 函數(shù)執(zhí)行后, 返回一個遍歷器對象,該對象本身也具有[Symbol.iterator]屬性,執(zhí)行后返回自身

next()方法的參數(shù)會作為上一條 yield 語句的返回值而存在

1.13.1 fibonacci

function * fibonacci(){
  let [prev,curr] = [0,1]
  while(1) { 
    [prev,curr] = [curr, prev+curr]
    yield prev
  }
}
for(let n of fibonacci()) { 
  if(n>10) break; 
  console.log(n); // 1,1,2,3,5,8
}

1.14 async await

一比較就會發(fā)現(xiàn)巨税,async函數(shù)就是將 Generator 函數(shù)的星號(*)替換成async,將yield替換成await,另外它內(nèi)置了執(zhí)行器: spawn 函數(shù)(不用使用co模塊了)

2. 函數(shù)節(jié)流throttle 和函數(shù)去抖 debounce

參考掘金 知乎專欄

定義:

css-tricks.com

實(shí)現(xiàn):

function throttle(fn, interval = 300) {
    let canRun = true;
    return function () {
        if (!canRun) return;
        canRun = false;
        setTimeout(() => {
            fn.apply(this, arguments);
            canRun = true;
        }, interval);
    };
}

function debounce(fn, interval = 300) {
    let timeout = null;
    return function () {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            fn.apply(this, arguments);
        }, interval);
    };
}

如果設(shè)置16.7ms 的話,更流暢的方法:
requestAnimationFrame()

The window.requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser call a specified function to update an animation before the next repaint. The method takes a callback as an argument to be invoked before the repaint.
可以將它看做一個鉤子鹃两,剛好卡在瀏覽器重繪前向我們的操作伸出橄欖枝遗座。

函數(shù) curry 化

Function.prototype.curry = function(){
  var args = arguments, that = this
  return function( ){
    return that.call(this, ...args, ...arguments)
  }
}

使用 js 添加 css 樣式表

1. 在head中插入新的link

    /**
    >在<head>中使用<link>標(biāo)簽引入一個外部樣式文件
    @param {string} url - css文件的鏈接
    */
    function includeLinkStyle(url) {
        var link = document.createElement("link");
        link.rel = "stylesheet";
        link.type = "text/css";
        link.href = url;
        document.getElementsByTagName("head")[0].appendChild(link);
    }

缺點(diǎn): 會被簡書屏蔽掉. 原因參考Content Security Policy 入門教程

2. addStyle

    var nums = document.styleSheets.length;
    var position = document.styleSheets[nums - 1].cssRules.length
    /**
    >添加一條 css 規(guī)則
    @param {string} str - css樣式
    */
    function addStyle(str) {
        document.styleSheets[nums - 1].insertRule(str, position++);
    }

要求 Content-Security-Policy 的 script 相關(guān)規(guī)則如下:content-security-policy: script-src 'self' 'unsafe-inline' 'unsafe-eval'

  • 允許執(zhí)行頁面內(nèi)嵌的<script>標(biāo)簽和事件監(jiān)聽函數(shù)
  • 允許將字符串當(dāng)作代碼執(zhí)行,比如使用eval俊扳、setTimeout途蒋、setInterval和Function等函數(shù)

3. addStyle 封裝

/**
>增加 sidebar 需要的全部樣式
@param {string} highlightColor - 高亮顏色, 默認(rèn)為'#c7254e'
*/
function addAllStyle(highlightColor) {
    highlightColor = highlightColor || "#c7254e"
    var sheet = newStyleSheet()
    /**
    >創(chuàng)建一個新的`<style></style>`標(biāo)簽插入`<head>`中
    @return {Object} style.sheet,`它具有方法insertRule`
    */
    function newStyleSheet() {
        var style = document.createElement("style");
        // 對WebKit hack :(
        style.appendChild(document.createTextNode(""));
        // 將 <style> 元素加到頁面中
        document.head.appendChild(style);
        return style.sheet;
    }
    var position = 0
    /**
    >添加一條 css 規(guī)則
    @param {string} str - css樣式,也可以是@media
    */
    function addStyle(str) {
        sheet.insertRule(str,position++);
    }
    addStyle(`@media only screen and (max-width : 1300px){
        .content-with-sidebar {
            margin-left:310px !important;
        }
    }`)
}

為什么 js 中 0.1+0.2 != 0.3

十進(jìn)制整數(shù)轉(zhuǎn)二進(jìn)制方法:除2取余;十進(jìn)制小數(shù)轉(zhuǎn)二進(jìn)制方法:乘2除整
十進(jìn)制0.1轉(zhuǎn)換成二進(jìn)制馋记,乘2取整過程:

0.1 * 2 = 0.2 # 0
0.2 * 2 = 0.4 # 0
0.4 * 2 = 0.8 # 0
0.8 * 2 = 1.6 # 1
0.6 * 2 = 1.2 # 1
0.2 * 2 = 0.4 # 0

.....

從上面可以看出号坡,0.1的二進(jìn)制格式是:0.0001100011....。這是一個二進(jìn)制無限循環(huán)小數(shù)梯醒,但計算機(jī)內(nèi)存有限宽堆,我們不能用儲存所有的小數(shù)位數(shù), 所以0.1 + 0.2 == 0.30000000000000004

C++中也是如此,printf("%20.20lf",0.1+0.2);得到0.30000000000000004441, 0.1+0.2 <= 0.3 //false"

js 實(shí)現(xiàn) new 操作符

1. 最基本的兩個功能, this綁定成員和 prototype 繼承

function New(f){
  var a = { }
  f.call(a)
  a.__proto__ = f.prototype
  return a
}

這兩行對應(yīng)原文中的小結(jié)2(this 綁定)小結(jié)3(proto鏈接), 另外, 小結(jié)1(constructor綁定)已經(jīng)被a.__proto__的賦值操作順帶完成了

2. 在1中未覆蓋到的new的細(xì)節(jié)

如果輸入函數(shù)f沒有返回值, 那么new f()會和上述的一樣返回構(gòu)建完成的Object, 但是考慮到函數(shù)f可能本身自帶返回值, 例如:

function f(name){
  this.name  = name
  if(Math.random() > 0.5)
    return name
  else 
    return { text:'I am Object' }
}

實(shí)際的情況正如原文中的小結(jié)4所述, - 若函數(shù)返回基本類型, 則new f()時會將生成好的對象返回

  • 若函數(shù)返回一個Object(包含Functoin, Array, Date,RegExg,Error)茸习,那么new表達(dá)式會尊重原函數(shù)的返回結(jié)果, 仍然返回這個Object

3. 總結(jié)上述兩點(diǎn),再額外加上處理輸入?yún)?shù)&new.target

function New(f){
    if(typeof f !== 'function'){
      throw 'New function the first param must be a function';
    }
    New.target = f;
    New.target.name = f.name
    //Object.create 是 newObj.__proto__ = f.prototype 的另一種寫法,原文說__proto__是瀏覽器實(shí)現(xiàn)的, 但實(shí)測node8也能用
    var newObj = Object.create(f.prototype);
    var argsArr = [].slice.call(arguments, 1);
    var o = f.apply(newObj, argsArr)
    New.target = undefined

    var isObject = typeof o === 'object' && o !== null;
    var isFunction = typeof o === 'function';
    if(isObject || isFunction){
        return o;
    }
    // 如果函數(shù)沒有返回`Object`那么`new`表達(dá)式中的函數(shù)調(diào)用會自動返回這個新的對象畜隶。
    return newObj;
}

深度比較兩個 Object 并輸出比較報告

function deepCompare(a, b) {
  var report = []
  compare(a, b)
  console.log(report)
  function compare(a, b, path) {
    path = path || ""
    if (path.length > 50 || !a || !b) return
    if (typeof a != typeof b) {
      report.push(`a${path} == ${a} , b${path} == $`)
      return
    }
    else if (typeof a == "object" && typeof b == "object") {
      for (var i in a) {
        if (a.hasOwnProperty && b.hasOwnProperty && a.hasOwnProperty(i) && !b.hasOwnProperty(i))
          report.push(`a${path}.${i} √ , b${path}[${i}] x`)
        else
          compare(a[i], b[i], path + "." + i)
      }
      for (var i in b) {
        if (!a[i] && b[i])
          report.push(`a${path}[${i}] x , b${path}[${i}] √`)
      }
    }
    else if ( a!=b ) {
      report.push(`a${path} == ${a} , b${path} == $号胚`)
    }
  }
}

indexedDB

// 讀取
var database
var request = indexedDB.open('threejs-editor', 1)
request.onsuccess = e => database = e.target.result

var transaction = database.transaction(['states'], 'readwrite')
var objectStore = transaction.objectStore('states')
var request = objectStore.get(0)
request.onsuccess = e => console.log(e.target.result)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末籽慢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子猫胁,更是在濱河造成了極大的恐慌嗡综,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杜漠,死亡現(xiàn)場離奇詭異极景,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)驾茴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門盼樟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锈至,你說我怎么就攤上這事晨缴。” “怎么了峡捡?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵击碗,是天一觀的道長。 經(jīng)常有香客問我们拙,道長稍途,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任砚婆,我火速辦了婚禮械拍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己坷虑,他們只是感情好甲馋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著迄损,像睡著了一般定躏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芹敌,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天痊远,我揣著相機(jī)與錄音,去河邊找鬼党窜。 笑死,一個胖子當(dāng)著我的面吹牛借宵,可吹牛的內(nèi)容都是我干的幌衣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼壤玫,長吁一口氣:“原來是場噩夢啊……” “哼豁护!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起欲间,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤楚里,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后猎贴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體班缎,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年她渴,在試婚紗的時候發(fā)現(xiàn)自己被綠了达址。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡趁耗,死狀恐怖沉唠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情苛败,我是刑警寧澤满葛,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站罢屈,受9級特大地震影響嘀韧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缠捌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一乳蛾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦肃叶、人聲如沸蹂随。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岳锁。三九已至,卻和暖如春蹦魔,著一層夾襖步出監(jiān)牢的瞬間激率,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工勿决, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乒躺,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓低缩,卻偏偏與公主長得像嘉冒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子咆繁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 系列文章導(dǎo)航 模塊(一) CommonJs,AMD, CMD, UMD 本文參考阮一峰 ES6入門 Module的...
    合肥黑閱讀 6,114評論 0 4
  • 先給 module 在網(wǎng)上找個自己感覺妥當(dāng)?shù)亩x讳推,module: 開發(fā)者將程序分解成離散功能塊,這些功能塊就稱為 ...
    YeLqgd閱讀 1,277評論 0 2
  • 模塊通常是指編程語言所提供的代碼組織機(jī)制玩般,利用此機(jī)制可將程序拆解為獨(dú)立且通用的代碼單元银觅。所謂模塊化主要是解決代碼分...
    MapleLeafFall閱讀 1,170評論 0 0
  • 模塊通常是指編程語言所提供的代碼組織機(jī)制,利用此機(jī)制可將程序拆解為獨(dú)立且通用的代碼單元坏为。所謂模塊化主要是解決代碼分...
    一個敲代碼的前端妹子閱讀 1,968評論 8 23
  • 寒冬已至究驴,在濟(jì)南的冬天,空氣似乎變個格外的凝滯匀伏,凜冽的寒風(fēng)使我瑟縮著纳胧。 感覺每呼吸一口,我就涼了一分帘撰。 作為一名瘦...
    小斗笠閱讀 203評論 0 0