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í)用
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é)果
那么匆笤,如果將上面代碼中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ù)組,必須具備以下條件:
- 該類(lèi)數(shù)組對(duì)象必須具有l(wèi)ength屬性砾赔,用于指定數(shù)組的長(zhǎng)度蝌箍。如果沒(méi)有l(wèi)ength屬性,那么轉(zhuǎn)換后的數(shù)組是一個(gè)空數(shù)組暴心。
- 該類(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) 是深拷貝還是淺拷貝
- 當(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 ]
- 當(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é)果:
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更安全一些