js幾個小技巧和坑

蝴蝶書看了,也知道充滿了毒瘤和糟粕,但該用仍是得用。html

實際寫了幾天,小技巧記錄下來。都是在py裏有直接答案,不會遇到的問題,沒想到js裏這麼費事。node

仍是要多讀《ES6標準入門》es6

1判斷object是[]仍是{}

主要是轉xml時是否正確,因此得判斷這個。沒想到這麼麻煩。數組

抄這個答案,http://www.javashuo.com/article/p-augptmsv-da.html框架

基本符合須要dom

if((Array.isArray(變量) && 變量.length === 0) || (Object.prototype.isPrototypeOf(變量) && Object.keys(變量).length === 0)){
                alert('該方法判斷了{}花括號這種狀況!');
}

2 deepcopy

obj = JSON.parse(JSON.stringify(o))

 3 根據object屬性值判斷object在array中的index

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex函數

var array1 = [5, 12, 8, 130, 44];

function findFirstLargeNumber(element) {
  return element > 13;
}

console.log(array1.findIndex(findFirstLargeNumber));
// expected output: 3

 4 boolean值邏輯取反用! 而不是~

js裏~是位取反。反正做爲邏輯判斷效果不對,記住和py不一樣就好了。性能

 

5 字符串format

node這樣寫spa

import util from "util";
const str_out = util.format('%s/%s.html',path, name)

es6裏這樣寫,反引號模板.net

const str_out = `${path}/${name}.html`;

node至關於py3.6以前的,寫法,而es6至關於py 3.6以後:

str_out = f'{path}/{name}.html'

仍是py 最簡潔 -_-!

 

反正如今的流行語言和框架,都是互相抄的。感受區別不是很大。

讓我決定語言取捨的,仍是擅長的領域,誰的庫更優雅,致使代碼更短,就用誰。

一切高級語言都是DSL語言,誠哉斯言。

 

6在NodeList作遍歷,map() 

dom操做時,有時會遇到NodeList,好比 element.childNodes  返回的就是這種。

通常對array,但願返回另外一個數組時用map(), 不但願返回值時用forEach()

若是但願經過map,對每個元素進行計算,返回1個數組:

const result = myNodeList.map((d)=>{ //do some compute}); 

會報錯:

.map is not a function

官方文檔說得很詳細,NodeList只是長得像Array,但並非Array,由於原型鏈和Array不一樣。

詳見 爲何 NodeList 不是數組?

 除了forEach方法,NodeList 沒有這些相似數組的方法。

官網給出了多種遍歷的方法,最簡單的就是最老實作for

    const results = [];
    for (let i = 0; i < myNodeList.length; ++i) {
        results.push(parser_item(myNodeList[i]));
    }

然而,這也太弱了好嗎,10多年前學C++ primer的時候最開始就是學在Vector上遍歷 而後push。這TM一點技術含量都沒有!

官網其餘方法也都沒有興趣,有點過於跑題了。語句要比這個更短,要一眼能看出我是在作遍歷map

仔細看文檔,發現NodeList有values()方法。在pandas之類的庫裏,這玩意一般是返回array的,有戲:

試了一下,這個返回的類型是

Object [Array Iterator]

哈哈,果真有戲,既然是個數組迭代器,那麼轉數組就很顯然了(繼續Google一番),最終解決方案:

const results = Array.from(myNodeList).map(parser_item);

稍微繞點脖子,可是仍是壓縮在了1行裏,並且肉眼可見 Array map 這些字眼,顯然我是在作相關的遍歷求值操做。

對於我這種只考慮可讀性,不考慮性能的人來講,能夠和上面的naive for循環說byebye了!

7 遍歷element.attributes

和前面相似,這玩意是個NamedNodeMap。

傳統操做

const attrMap = element.attributes;
for(let i = 0; i < attrMap.length; i++){
    let key = attrMap[i].nodeName;
    let value = attrMap[i].nodeValue;
}

或者不遍歷的狀況,直接

element.getAttribute(‘屬性名’);

那麼參考上面的作法,但仍是稍微複雜點,要用到Array的reduce

https://stackoverflow.com/questions/26264956/convert-object-array-to-hash-map-indexed-by-an-attribute-value-of-the-object

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

const results = Array.from(element.attributes)
                        .filter((item) => {return !excludes.includes(item.name);})
                        .reduce((res, item) =>{
                             res[item.name]=item.value;
                             return res;
                         },{});

遇到兩個坑,卡了很長時間。第一個坑是 reduce 的第一個參數累積函數,每次必需要返回累積後的結果 也就是return res; 這裏初始值是{},每次往裏塞一個屬性值。

第二個坑,是py和js徹底不一樣的地方,下面說。

8 判斷 元素在數組中

這個是py玩家基本必中的天坑了。

py裏 太習慣 了 

if x in list_a:

     pass

if x not in dict_b:

     pass

可是,在js裏,in已經被佔爲其餘用途了:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/in

若是指定的 屬性在指定的對象或其原型鏈中,則 in 運算符返回 true
例子不少,只要看一點就夠了
// 數組
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees // 返回true
3 in trees // 返回true
6 in trees // 返回false
"bay" in trees // 返回false (必須使用索引號,而不是數組元素的值)

"length" in trees // 返回true (length是一個數組屬性)

 

 
也就是說,js裏的in關鍵字
'property' in a

大約等於py裏的 hasattr()函數

hasattr(a, 'property')

這TM坑爹呢!

js裏真正和py裏in關鍵字同樣做用的是
a.includes(element)

 9判斷代碼運行在node仍是browser

var isBrowser = typeof window !== 'undefined'
    && ({}).toString.call(window) === '[object Window]';

var isNode = typeof global !== "undefined" 
    && ({}).toString.call(global) === '[object global]';
相關文章
相關標籤/搜索