Javascript 技法100第一篇

1. 神乎其技的 + 號(hào)

//使用 `+` 運(yùn)算符可以快速將一個(gè)字符串?dāng)?shù)值轉(zhuǎn)化為數(shù)字
console.log(typeof '1');  //string
console.log(typeof +'1');  //number

//Date類型會(huì)轉(zhuǎn)化為number類型的時(shí)間戳小压,精確到ms
console.log(+new Date())  //1484219585488

//相比這種方式轉(zhuǎn)換時(shí)間戳簡(jiǎn)便睁宰,Date.parse()只精確到s澳眷,ms的位置都為0
console.log(Date.parse(new Date()))  //'1484219585000'

//無(wú)法轉(zhuǎn)換為有效的數(shù)字一般會(huì)得到NaN
console.log(+'abc') //NaN
console.log(+function(){})  //NaN

//數(shù)組有點(diǎn)奇特
console.log(+[1,2,3]);  //NaN
console.log(+[]);  //0
console.log(+[5]);  //5

//這還就導(dǎo)致了
console.log(++[[]][+[]]+[+[]])  //10

//為什么呢?一臉懵逼的你一定愿意看看推導(dǎo)

+[] = 0
  =>  ++[[]][+[]]+[+[]] = ++[[]][0]+[0] 

[[]][0] = []
  =>  ++[[]][0] = ++[] = [] + 1 = '' + '1' =  '1'

//++運(yùn)算符得到的結(jié)果一定是number甫题,所以有必要用 + 號(hào)再一次轉(zhuǎn)換類型

++[] = +( [] + 1 ) = +'1' = 1
  =>  1 + [0] = '1' + '0' = '10'

2. 妙用數(shù)組length屬性

var a = [1, 2, 3, 4];

console.log(a.length)   //4

//清空數(shù)組
a.length = 0;   //a = []

//截取數(shù)組
a.length = 2;   //a = [1, 2]

//擴(kuò)張數(shù)組派敷,用undefined填充
a.length = 5;   //a = [1, 2, 3, 4, undefined]

3. 兩個(gè)數(shù)花式交換

//方案一
var a = 1, b =2;
a = [b, b = a][0];
console.log(a, b);  //2 1

//方案二
var a = 1, b =2;
a = a ^ b;
b = a ^ b;
a = a ^ b;
console.log(a,b)  //2 1

4. 在讀取length的循環(huán)中緩存length

var a = [1, 2, 3];
for(var i = 0; i < a.length; i++){
    console.log(a[i])
}

盡管上面的做法沒(méi)有異議,但每次循環(huán)都會(huì)額外做一個(gè)計(jì)算數(shù)組length的操作衙荐,數(shù)組足夠小的時(shí)候這當(dāng)然沒(méi)有任何問(wèn)題,但當(dāng)它足夠大浮创,它就會(huì)成為拖垮性能的一個(gè)元兇忧吟。假如你嘗試過(guò)在java中處理一個(gè)超大文件的每一個(gè)字節(jié)時(shí)使用上面的做法,你可能會(huì)懂得它對(duì)性能的破壞力有多大斩披。

必要的時(shí)候采用下面這種做法吧:

var a = [1, 2, 3];
for(var i = 0, len = a.length; i < len; i++){
    console.log(a[i]);
}

5. 可動(dòng)態(tài)指定地訪問(wèn)Object屬性

var o = {
    name : 'cmx',
    age : 24
}
//可以這么訪問(wèn)一個(gè)key
console.log(o.name);

//還可以這么訪問(wèn)一個(gè)key
console.log(a['name']);

//再直白一點(diǎn)
var key = 'name';
console.log(a[key]);

看完你能知道應(yīng)用場(chǎng)景嗎溜族?

6. 妙用And和Or

//設(shè)置變量的初始默認(rèn)值
function(a){
    a = a || '默認(rèn)值';
}

//代替if語(yǔ)句,利用短路特性雏掠,如果a變量是有效值(非undefined斩祭、null劣像、""乡话、false、0等)耳奕,執(zhí)行方法dosomething
a && dosomething(a);

//同理绑青,a為無(wú)效值時(shí)執(zhí)行dosomething函數(shù)
a || dosomething();

7. 數(shù)組拼接

存在兩種方式去拼接兩個(gè)數(shù)組:

var a = [1,2];
var b = [3];

//生成一個(gè)新的數(shù)組,不破壞原數(shù)組
a = a.concat(b)    //a=[1,2,3]

//以第一個(gè)參數(shù)數(shù)組作為this屋群,第二個(gè)參數(shù)數(shù)組作為遍歷參數(shù)闸婴,push進(jìn)第一個(gè)數(shù)組,最終第一個(gè)數(shù)組為兩個(gè)數(shù)組的拼接芍躏,第二個(gè)數(shù)組不改變
Array.prototype.push.apply(a, b)    //a=[1,2,3] b=[3]

//相當(dāng)于
a.push(b[0], b[1], b[2]..)

什么時(shí)候用哪種呢邪乍?concat由于生成新的數(shù)組,必然是占內(nèi)存的对竣,但它不限制合并數(shù)組大小庇楞。而第二種方法存在合并數(shù)組個(gè)數(shù)限制(實(shí)際上是函數(shù)的形參個(gè)數(shù)限制,不超過(guò)65536)否纬,內(nèi)存則相對(duì)于concat減少了一個(gè)合并后數(shù)組的大小吕晌。性能上相差不多。

8. 兩個(gè)操作符typeof跟instanceof

  • typeof判斷變量的類型临燃,為一元運(yùn)算符
  • instanceof判斷變量的實(shí)例(原型鏈)睛驳,為二元運(yùn)算符

用法上烙心,

console.log(typeof {name:'chenmuxin'}) //'object'

console.log({name:'chenmuxin'} instanceof Object)  //true

typeof返回的是一個(gè)全小寫字符串,依據(jù)變量的類型可能會(huì)返回:

'object'乏沸、'number'淫茵、'string''undefined'蹬跃、'function'痘昌、'boolean''symbol'

如你所見炬转,不存在數(shù)組類型辆苔。數(shù)組返回的是'object',不僅數(shù)組扼劈,所有諸如Date驻啤、RegExp都被作為object看待

'number'類型:

typeof 1
typeof(1)   //也可以這樣使用,類似java
typeof 3.1415   //js的number類型統(tǒng)一了整型浮點(diǎn)型等
typeof NaN  //Not a number表示的是無(wú)窮和非數(shù)值荐吵,它是一個(gè)number類型
typeof Number(1)    //Number類直接返回的類型也是number

'undefined'類型:

typeof undefined
typeof i_am_undeclared  //一個(gè)未聲明變量

var i_am_declared_but_undefined_value;  //一個(gè)已聲明但未賦值變量
typeof i_am_declared_but_undefined_value

最容易迷惑情形:

typeof new Number(1)    //返回'object'骑冗,使用new操作符時(shí),諸如String先煎、Boolean等引用類返回的是object
typeof Number(1)    //'number'

typeof null //返回'object'贼涩,js誕生之時(shí)起,null就是跟object同類型薯蝎,這顯然不合適遥倦。但es6的提案typeof null == 'null'被否決,所以目前都還只能這么認(rèn)識(shí)它

typeof /a/  //正則在不同瀏覽器上可能有不同類型占锯,可能是function袒哥,也可能是object,標(biāo)準(zhǔn)是object消略。判斷正則應(yīng)使用instanceof

使用instanceof時(shí)堡称,首先要保證對(duì)象可以new,只有允許new才會(huì)存在所謂實(shí)例艺演。所以想使用instanceof判斷一個(gè)基本變量的類型是不可行的却紧。

console.log(1 instanceof Number) //false

數(shù)組無(wú)法使用typeof來(lái)判斷,但可以使用instanceof(一定場(chǎng)景下會(huì)失敗胎撤,例如多重iframe)

console.log([1] instanceof Array)  //true

當(dāng)然也可以使用更穩(wěn)妥的數(shù)組的方法:

console.log(Array.isArray([1])) //true

總結(jié):像數(shù)組晓殊、正則等繼承自Object但具體的對(duì)象(首先可以new),我們一般都可以用instanceof去判斷哩照。像很多基本變量以及它們的引用類型挺物,我們就用typeof去判斷。

9. in和for遍歷

var a = [10,20,30];
var b = {name : 'cmx'}

//基本數(shù)組遍歷
for(var i=0,length = a.length; i < length; i++){
    console.log(a[i]);
}

//of運(yùn)算符每次循環(huán)直接得到數(shù)組值
for(var i of a){
    console.log(i);
}

//in運(yùn)算符每次循環(huán)得到當(dāng)前下標(biāo)
for(var i in a){
    console.log(a[i]);
}

//in運(yùn)算符遍歷對(duì)象時(shí)飘弧,每次得到對(duì)象的key
for(var i in b){
    console.log(i);
    console.log(b[i]);
}

存在一些特殊情況识藤,in遍歷時(shí)砚著,不僅會(huì)把數(shù)組(或?qū)ο螅┑拿恳粋€(gè)下標(biāo)(key)遍歷出來(lái),一旦像下面這樣定義了原型屬性或方法

Array.prototype.what = function(){ }

in遍歷還會(huì)把它們一起遍歷出來(lái)痴昧,這里得到一個(gè)what稽穆。如果沒(méi)有作必要的判斷往往會(huì)導(dǎo)致如下:

for(var i in a){
    //打印a[what]出錯(cuò)
    console.log(a[i]);
}

要么不使用原型直接添加的方式,而使用Object.defineProperty并設(shè)置可枚舉屬性為false赶撰。要么就in遍歷數(shù)組時(shí)舌镶,都判斷當(dāng)前i是否為number類型:

var a = [1, 2, 3];
Array.prototype.cmx = 5;

for(var i in a){
    //+i是因?yàn)閕遍歷出來(lái)的都是字符串形式。至于為什么不使用 i != NaN 豪娜,因?yàn)槿我鈨蓚€(gè)NaN不相等啊
    if(!Number.isNaN(+i)){
        console.log(i)
    }
}

因?yàn)樵蛿U(kuò)展是不允許添加一個(gè)number類型的餐胀,所以上面的做法成立。

Array.prototype.1 = 1 //error

或者使用通用的方法(同時(shí)適合數(shù)組和對(duì)象)

for(var i in a){
    if(a.hasOwnProperty(i)){
        console.log(a[i])
    }
}

Object.prototype.hasOwnProperty()會(huì)忽略對(duì)象原型鏈上的屬性和方法瘤载。

10. call和apply

我們先來(lái)看段代碼:

function Chen(){
    this.name = '老陳';
    
    this.sayHello = function(hello){
        console.log('我是老陳的方法');
        console.log(hello + '否灾, I am ' + this.name);
    }
}

function Huang(){
    this.name = '老黃';
    
    this.sayHello = function(hello){
        console.log('我是老黃的方法');
        console.log(hello + ', I am ' + this.name);
    }
}

var chen = new Chen();
chen.sayHello('你好');    //我是老陳的方法  你好鸣奔, I am 老陳

var huang = new Huang();

chen.sayHello.call(huang,'Hello');  //我是老陳的方法  Hello墨技, I am 老黃

chen.sayHello.apply(huang,['Hi'])  //我是老陳的方法  Hi, I am 老黃

callapply非常像挎狸,都是為一個(gè)函數(shù)指定上下文扣汪,并傳入?yún)?shù)。唯一的區(qū)別在于參數(shù)參入的形式锨匆。

Function.prototype.call(thisObj, ...args)
Function.prototype.apply(thisObj[, argArray])

call()thisObj作為上下文帶上若干個(gè)指定的參數(shù)值調(diào)用某個(gè)函數(shù)或方法崭别,參數(shù)必須展開。

apply()thisObj作為上下文帶上一個(gè)數(shù)組或累數(shù)組參數(shù)調(diào)用某個(gè)函數(shù)或方法统刮,參數(shù)必須組合成一個(gè)數(shù)組紊遵。

由于只是形式不同,故以其中一個(gè)作為示例說(shuō)明:

chen.sayHello.call(huang, 'Hello')

huang作為上下文侥蒙,調(diào)用chensayHello方法,由于chen.sayHello()調(diào)用的this.name已經(jīng)被更改為huang.name匀奏,所以得到上面的執(zhí)行結(jié)果鞭衩。

call或者apply來(lái)模擬一下繼承:

function Boy(name, love){
    this.name = name;
    this.lova = love;
    
    this.say = function(){
        console.log('I am '+ name +',I like '+ love +'娃善,what about you?');
    }
}

function BadBoy(name, love){
    Boy.call(this, name, love);
    
    this.do = function(){
        console.log('I made a mistake!');
    }
}

var badBoy = new BadBoy('張三','打架');
badBoy.say();   //I am 張三论衍,I like 打架,what about you?
badBoy.do();    //I made a mistake!

var boy = new Boy('李四','學(xué)習(xí)');
boy.say();  //I am 李四聚磺,I like 學(xué)習(xí)坯台,what about you?
boy.do();   //boy.do is not a function

(轉(zhuǎn)載請(qǐng)注明出處,簡(jiǎn)書-沐心chen)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瘫寝,一起剝皮案震驚了整個(gè)濱河市蜒蕾,隨后出現(xiàn)的幾起案子稠炬,更是在濱河造成了極大的恐慌,老刑警劉巖咪啡,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件首启,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡撤摸,警方通過(guò)查閱死者的電腦和手機(jī)毅桃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)准夷,“玉大人钥飞,你說(shuō)我怎么就攤上這事∩狼叮” “怎么了代承?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)渐扮。 經(jīng)常有香客問(wèn)我论悴,道長(zhǎng),這世上最難降的妖魔是什么墓律? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任膀估,我火速辦了婚禮,結(jié)果婚禮上耻讽,老公的妹妹穿的比我還像新娘察纯。我一直安慰自己,他們只是感情好针肥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布饼记。 她就那樣靜靜地躺著,像睡著了一般慰枕。 火紅的嫁衣襯著肌膚如雪具则。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天具帮,我揣著相機(jī)與錄音博肋,去河邊找鬼。 笑死蜂厅,一個(gè)胖子當(dāng)著我的面吹牛匪凡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掘猿,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼病游,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了稠通?” 一聲冷哼從身側(cè)響起衬衬,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤买猖,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后佣耐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體政勃,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年兼砖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奸远。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡讽挟,死狀恐怖懒叛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耽梅,我是刑警寧澤薛窥,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站眼姐,受9級(jí)特大地震影響诅迷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜众旗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一罢杉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贡歧,春花似錦浓冒、人聲如沸巢掺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至绍弟,卻和暖如春技即,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晌柬。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工姥份, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人年碘。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像展鸡,于是被迫代替她去往敵國(guó)和親屿衅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

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

  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,237評(píng)論 0 4
  • 語(yǔ)法基礎(chǔ) - 詞法 字符集 Unicode字符集, 區(qū)分大小寫 注釋 // /* */ 直接量 數(shù)字 小數(shù) 字符串...
    KeKeMars閱讀 877評(píng)論 1 11
  • 寫過(guò)的詩(shī) 都是垃圾碎片 生活過(guò)的歲月 都是煉獄場(chǎng) 幻想是一只令人 垂憐的花朵 對(duì)著湖面不停地 嘆息自己的美麗 不被...
    枝樓閱讀 188評(píng)論 0 0
  • 沉醉在春風(fēng)里 那些美好 恍惚 閃爍 浩蕩春光 光陰深靜 聽一曲春風(fēng)引 等待重逢
    夏天里的飛天喵閱讀 289評(píng)論 2 1
  • 樓市政策不斷出臺(tái)涡尘,調(diào)控力度不斷加深,很多準(zhǔn)備入手買房或觀望的人在此時(shí)下手一定要注意了响迂,別讓自己辛辛苦苦籌集的首付和...
    哈思琪閱讀 247評(píng)論 0 0