前端學(xué)習(xí)之路[node](一)

node文件中可以直接訪(fǎng)問(wèn)的:

process  進(jìn)程
buffer 緩沖區(qū)
clearImmediate setImmediate
clearTimeout
...
...

js獲取頁(yè)面上的所有標(biāo)簽

new Set([...document.querySelectorAll('*')].map(v => v.tagName));

15732892883 正則變成這樣 157xxxx2883

let str = '15732892883'
console.log(str.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2'));

在命令行配置process.env環(huán)境變量:

mac中使用 export NODE_ENV=dev
windows中使用 set NODE_ENV=dev
所以就會(huì)出現(xiàn)一些第三方包去處理這些兼容性的問(wèn)題

node基于common.js
node中一個(gè)文件就是一個(gè)模塊(其實(shí)是一個(gè)閉包自執(zhí)行函數(shù))

(function (exports require module __filename, __dirname) {})()

node中自己寫(xiě)的模塊需要使用相對(duì)路徑進(jìn)行引用

注意他們之間的關(guān)系
module.exports = exports = this = {}

require方法具有緩沖功能,多次引用只會(huì)執(zhí)行一次

npm的一些操作:

npm root -g // 查看全局模塊的安裝位置
npm list --depth=0 -g  //查看全局都安裝了那些包
nrm  //快速切換npm的源
nvm  // 快速切換node的版本, mac下有個(gè)n命令也能切換

nrm 的簡(jiǎn)單實(shí)用

image

http-server

幫我們啟動(dòng)一個(gè)本地服務(wù),類(lèi)似這樣的能提供服務(wù)還有live-server

npm install -g http-server
http-server  //在某個(gè)路徑下啟動(dòng)服務(wù)

node中讀取文件怎么樣更加優(yōu)雅

1. 自己寫(xiě)一個(gè)函數(shù)封裝成promise
const fs = require('fs')

function read (url) {
    return new Promise((resolve, reject) => {
        fs.readFile(url, 'utf8', function (err, data) {
            if(err) return reject(err)
            resolve(data)
        })
    })
}

read('./b.js').then(res => {
    console.log(res)
}, err => {
    console.log(err)
})


2.利用node中的util中的promisify,將異步分裝為promise
const fs = require('fs')
const util  = require('util');

let read = util.promisify(fs.readFile)  //處理成了promise

read('./b.js','utf8').then(res => {
    console.log(res);
}, err => {
    console.log(res)
})

3. 在2的基礎(chǔ)上用async 和 await 更加優(yōu)雅
async function result () {
    let content1 = await read('./a.js')
    let content2 = await read('./b.js')
    let str = content1 + content2
    console.log(str)
}

node遞歸創(chuàng)建目錄

const fs = require('fs')
function makep (url, cb) {
    let urlArr = url.split('/');
    let index = 0;
    function make (path) {
        if(urlArr.length < index) return cb('創(chuàng)建完成')
        fs.stat(path, function (err) {
            if (err) { //如果不在這個(gè)目錄
                fs.mkdir(path, function (err) {
                    if(err) return cb(err)
                    make(urlArr.slice(0, ++index+1).join('/'))
                })
            } else {// 如果存在就跳到下一次創(chuàng)建
                make(urlArr.slice(0, ++index+1).join('/'))
            }
        })
    }
    make(urlArr[index])
}

makep('./aa/bb/cc', function (e) {
    console.log(e)
})

path模塊下path.resolve() 和 path.join()區(qū)別

這兩者都是用來(lái)組裝路徑的
path.join 產(chǎn)生**相對(duì)**路徑
console.log(path.join('/a', './img/so')); // \a\img\so
path.join也能產(chǎn)生**絕對(duì)**路徑用__dirname拼接
console.log(path.join(__dirname, './img/so')); // F:\gongzuo\test\img\so
path.resolve 產(chǎn)生的是**絕對(duì)**路徑
console.log(path.resolve('a', './img/so'));  // F:\gongzuo\test\a\img\so

發(fā)布訂閱模式

node中已經(jīng)很好的實(shí)現(xiàn)了發(fā)布訂閱 http://nodejs.cn/api/events.html

node中的實(shí)現(xiàn)

// 引入node的內(nèi)置模塊
let EventEmitter = require('events');
let {inherits} = require('util')
function Dog() {}
inherits(Dog, EventEmitter)  // 相當(dāng)于Dog.prototype.__proto__ = EventEmitter.prototype
let pup = new Dog()
// 訂閱
pup.on('dark', () => {
  console.log('旺旺')
})
// 發(fā)布
pup.emit('dark')

自己實(shí)現(xiàn)一下

class EventEmitter {
  constructor() {
    this._event = {}
  }
  // 訂閱
  on (eventName, cb) {
    if(this._event[eventName]){
      this._event[eventName].push(cb)
    } else {
      this._event[eventName] = [cb]
    }
  }
  // 發(fā)布
  emit (eventName, ...args) {
    if(this._event[eventName]) {
      this._event[eventName].forEach(fn => fn(...args))
    }
  }
  // 移除某個(gè)訂閱
  removeListener (eventName, cb) {
    if(this._event[eventName]) {
      this._event[eventName] = this._event[eventName].filter(fn => fn !== cb)
    }
  }
  // 實(shí)現(xiàn)once執(zhí)行一次
  once (eventName, cb) {
    let fn = (...args) => {
      cb(...args)
      this.removeListener(eventName, fn)
    }
    this.on(eventName, fn)
  }
}

//利用once只訂閱一次
let event = new EventEmitter()
// 觸發(fā)一次
event.once('cry', (mode) => {
  console.log(`哭的模式:${mode}`)
})
// 發(fā)布(觸發(fā))哭操作
event.emit('cry', '大哭')
event.emit('cry', '大哭')

md中的折疊語(yǔ)法

<details>
<summary>內(nèi)容描述</summary>
這里是具體的內(nèi)容描述
</details>

<details>
<summary>內(nèi)容描述</summary>
<md>這里是具體的內(nèi)容描述</md>
</details>

Array.from()

Array.from()方法就是將一個(gè)類(lèi)數(shù)組對(duì)象或者可遍歷對(duì)象轉(zhuǎn)換成一個(gè)真正的數(shù)組。

將類(lèi)數(shù)組對(duì)象轉(zhuǎn)換為真正數(shù)組:

let arrayLike = {
    0: 'tom', 
    1: '65',
    2: '男',
    3: ['jane','john','Mary'],
    'length': 4
}
let arr = Array.from(arrayLike)
console.log(arr) // ['tom','65','男',['jane','john','Mary']]

結(jié)果


image

那么匆笤,如果將上面代碼中l(wèi)ength屬性去掉呢驳庭?實(shí)踐證明,答案會(huì)是一個(gè)長(zhǎng)度為0的空數(shù)組幌蚊。

這里將代碼再改一下,就是具有l(wèi)ength屬性,但是對(duì)象的屬性名不再是數(shù)字類(lèi)型的诗鸭,而是其他字符串型的,代碼如下:

let arrayLike = {
    'name': 'tom', 
    'age': '65',
    'sex': '男',
    'friends': ['jane','john','Mary'],
    length: 4
}
let arr = Array.from(arrayLike)
console.log(arr)  // [ undefined, undefined, undefined, undefined ]

會(huì)發(fā)現(xiàn)結(jié)果是長(zhǎng)度為4参滴,元素均為undefined的數(shù)組

由此可見(jiàn)强岸,要將一個(gè)類(lèi)數(shù)組對(duì)象轉(zhuǎn)換為一個(gè)真正的數(shù)組,必須具備以下條件:

  1. 該類(lèi)數(shù)組對(duì)象必須具有l(wèi)ength屬性砾赔,用于指定數(shù)組的長(zhǎng)度蝌箍。如果沒(méi)有l(wèi)ength屬性,那么轉(zhuǎn)換后的數(shù)組是一個(gè)空數(shù)組暴心。
  2. 該類(lèi)數(shù)組對(duì)象的屬性名必須為數(shù)值型或字符串型的數(shù)字

將Set結(jié)構(gòu)的數(shù)據(jù)轉(zhuǎn)換為真正的數(shù)組:

let arr = [12,45,97,9797,564,134,45642]
let set = new Set(arr)
console.log(Array.from(set))  // [ 12, 45, 97, 9797, 564, 134, 45642 ]

Array.from還可以接受第二個(gè)參數(shù)妓盲,作用類(lèi)似于數(shù)組的map方法,用來(lái)對(duì)每個(gè)元素進(jìn)行處理专普,將處理后的值放入返回的數(shù)組悯衬。如下

let arr = [1,2,3,4,5,6,7]
let set = new Set(arr)
console.log(Array.from(set, item => item + 1)) // [ 2, 3, 4, 5, 6, 7, 8 ]

去除字符串里面的重復(fù)字符

console.log([...new Set('abcddd')].join('')); // abcd

數(shù)組去重

function dedupe(array) {
  // return Array.from(new Set(array)); 這種通過(guò)Array.from
  return [...new Set(array)];  // 這種通過(guò)解構(gòu)
}

dedupe([1, 1, 2, 3]) // [1, 2, 3]

求數(shù)組的并集

let a = [1, 2, 3];
let b = [4, 3, 2];

// 并集
let union = [...new Set([...a, ...b])];
console.log(union); //[1, 2, 3, 4]

求數(shù)組的交集與差集

let a = [1, 2, 3];
let b = new Set([4, 3, 2]);

// 交集
let intersect = [...new Set(a.filter(x => b.has(x)))];
console.log(intersect); // [2,3]

// 差集
let difference = [...new Set(a.filter(x => !b.has(x)))];
console.log(difference); //[1]

slice(0) 是深拷貝還是淺拷貝

  1. 當(dāng)數(shù)組中的元素都是非引用類(lèi)型時(shí): 可以實(shí)現(xiàn)深拷貝
let arr = [1,2,3,4]
let human = arr.slice(0);
human[0] = 'nanfeiyan';
console.log(arr) // [ 1, 2, 3, 4 ]
console.log(human) //[ 'nanfeiyan', 2, 3, 4 ]
  1. 當(dāng)數(shù)組中的元素有引用類(lèi)型時(shí): 不可以實(shí)現(xiàn)深拷貝
var obj = [
    {
        name:'melin1',
        job:'111'
    },
    {
        name:'melin2',
        job:'222'
    },
    {
        name:'melin3',
        job:'333'
    }
];
var copy = obj.slice(0);
copy[1].name = 'tom';
console.log(obj[1].name); //tom
console.log(copy[1].name); //tom

for in 和 for of的區(qū)別

for in

let arr = [1,2,3,5,6,3];
arr.name = 'liguigong';
Array.prototype.jj = function () {
  console.log(230)
}
for(let i in arr) {
  console.log(i)
}

結(jié)果:


image

for of

因?yàn)槟軌虮籪or...of正常遍歷的,都需要實(shí)現(xiàn)一個(gè)迭代器Iterator,
而數(shù)組檀夹、字符串筋粗、Set、Map和NodeList結(jié)構(gòu)炸渡,早就內(nèi)置好了Iterator(迭代器)娜亿,它們的原型中都有一個(gè)Symbol.iterator方法, 而Object對(duì)象并沒(méi)有實(shí)現(xiàn)這個(gè)接口,使得它無(wú)法被for...of遍歷

Array.prototype[Symbol.iterator];
 
// ? values() { [native code] }
 
String.prototype[Symbol.iterator];
 
// ? [Symbol.iterator]() { [native code] }
 
Set.prototype[Symbol.iterator];
 
// ? values() { [native code] }
 
Map.prototype[Symbol.iterator];
 
// ? entries() { [native code] }

NodeList.prototype[Symbol.iterator];
 
// ? entries() { [native code] }
Object.prototype[Symbol.iterator];
// undefined 

如果想遍歷Object類(lèi)型怎么操作,給對(duì)象加上遍歷器

let obj = {
  name: "XX",
  age: 20,
  job: 'teacher',
  [Symbol.iterator]() {
    const self = this;
    const keys = Object.keys(self);
    let index = 0;
    return {
      next() {
        if (index < keys.length) {
          return {
            value: self[keys[index++]],
            done: false
          };
        } else {
          return { value: undefined, done: true };
        }
      }
    };
  }
};

for (let item of obj) {
  console.log(item)
}
// XX 20 teacher

git的一些操作:

git stash //將此時(shí)更改的內(nèi)容暫存起來(lái)(此時(shí)就可以切換到其他分支就行操作了,
等處理完在切回本分支(git checkout 分支名), 還原以前的,繼續(xù)操作)
git stash apply //恢復(fù)卻不刪除stash的內(nèi)容
git stash pop  //恢復(fù)并且刪除stash信息
git stash list // 查看此時(shí)的暫存列表
git stash drop  // 刪除這個(gè)分支上的所有的stash

git checkout . 和 git reset 和 git reset --hard 提交信息編號(hào)之間的區(qū)別

git checkout .    //將工作區(qū)的代碼恢復(fù)到上一次commit之前
git reset .  //將暫存區(qū)的內(nèi)容恢復(fù)到工作區(qū)
git reset --hard 提交信息編號(hào)之間的區(qū)別  //回到指定的版本
git add . //將工作區(qū)的內(nèi)容添加到暫存區(qū)
git add . 和 git reset . 是相反的兩對(duì)

git fetch和git pull的區(qū)別

git fetch 相當(dāng)于是從遠(yuǎn)程獲取最新到本地蚌堵,不會(huì)自動(dòng)merge
git pull:相當(dāng)于是從遠(yuǎn)程獲取最新版本并merge到本地
git pull 相當(dāng)于從遠(yuǎn)程獲取最新版本并merge到本地
在實(shí)際使用中买决,git fetch更安全一些
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吼畏,隨后出現(xiàn)的幾起案子策州,更是在濱河造成了極大的恐慌,老刑警劉巖宫仗,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異旁仿,居然都是意外死亡藕夫,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)枯冈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)毅贮,“玉大人,你說(shuō)我怎么就攤上這事尘奏√踩欤” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵炫加,是天一觀的道長(zhǎng)瑰煎。 經(jīng)常有香客問(wèn)我铺然,道長(zhǎng),這世上最難降的妖魔是什么酒甸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任魄健,我火速辦了婚禮,結(jié)果婚禮上插勤,老公的妹妹穿的比我還像新娘沽瘦。我一直安慰自己,他們只是感情好农尖,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布析恋。 她就那樣靜靜地躺著,像睡著了一般盛卡。 火紅的嫁衣襯著肌膚如雪助隧。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天窟扑,我揣著相機(jī)與錄音喇颁,去河邊找鬼。 笑死嚎货,一個(gè)胖子當(dāng)著我的面吹牛橘霎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播殖属,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼姐叁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了洗显?” 一聲冷哼從身側(cè)響起外潜,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挠唆,沒(méi)想到半個(gè)月后处窥,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玄组,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年滔驾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俄讹。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡哆致,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出患膛,到底是詐尸還是另有隱情摊阀,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站胞此,受9級(jí)特大地震影響臣咖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜豌鹤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一亡哄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧布疙,春花似錦蚊惯、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至儒溉,卻和暖如春宦焦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背顿涣。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工波闹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人涛碑。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓精堕,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蒲障。 傳聞我的和親對(duì)象是個(gè)殘疾皇子歹篓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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