JavaScript紅色警戒

JS紅色警戒

JS有很多讓人迷惑的地方点晴,一起來看看吧。

with

with可以擴展作用域鏈瓮下,建議永遠不要使用它盖腕。我們來看看這些列子。

案例1

正常用法

function People(name){
    this.name = name;
    this.eat = function(){
        console.log(this.name+"要吃飯");
    }
}
var me = new People("xiaohu");

with(me){
    console.log(name);//可以省略me.
    eat();//可以省略me.
}

看起來很方便的樣子并巍。

with讓閱讀代碼的人很瘋狂

看看下面的代碼

with(me){
    console.log(name);
    eat();
    play=function(){//如果是省略了me.,那么play應(yīng)該定義在對象me中
        console.log(this.name);
    }
    nickName="xiao" + name;//如果是省略了me.,那么nickName應(yīng)該定義在對象me中
}

我們運行一下就知道目木,兩個變量變成了全局變量。

案例2

正常用法

function People(name){
    this.name = name;
    this.property={
        wallet:{
            banknote:1000,
            coin:20,
            salary:9
        }
    };
    this.eat = function(){
        console.log(this.name+"要吃飯");
    }
}
var me = new People("xiaohu");
var salary=2000;
with(me.property.wallet){//好像很方便啊
    banknote+=salary;//等等懊渡,salary到底是me.property.wallet還是哪兒的肮羯洹?
    console.log(banknote);
}

with讓閱讀代碼的人很瘋狂

我們還是用其他方法吧剃执。

var salary=2000;
var wallet = me.property.wallet;
wallet.banknote+=salary;
console.log(wallet.banknote);

像這樣緩存起來就很好var wallet = me.property.wallet;

eval

eval容易出錯

JS的eval可能會使代碼不清晰誓禁,影響調(diào)試和性能,應(yīng)該避免使用肾档∧∏。看看下面這段代碼。

function Workers(){
    this.assignment=function assignment(who, number){
        eval("this.work" + who + "='finish task:"+number+"'");
    }
}
var workers = new Workers();
for (var i = 0; i < 5; i++) {
    workers.assignment(i,i);
}

這段代碼給工人分配工作怒见,在對象workers創(chuàng)建很多的屬性俗慈,eval實際上想執(zhí)行這樣的語句workers.work1='finin task:1'。在參數(shù)一切正常的情況下是可以很好的工作的速种,但是這個函數(shù)是很容易出錯的姜盈。
像下面這樣傳入空格,“'”等字符串的結(jié)束標記配阵,都會讓eval嘗試運行的語句是不合法的,非常容易出錯示血,也不容易調(diào)試棋傍。

workers.assignment("1   1","'");

eval最常見的錯誤就是像上面這樣給對象加很多屬性,其實用數(shù)組就可以很好的實現(xiàn)同樣的功能∧焉螅看看下面的代碼瘫拣。

function WorkersBetter(){
    this.workers=[];
    this.assignment=function assignment(name, task){
        //TODO: 檢查數(shù)組越界......
        var obj ={name:name,task:task};
        this.workers.push(obj);
    }
}
var workersBetter = new WorkersBetter();

for (var i = 0; i < 3; i++) {
    workersBetter.assignment(i,"task"+i);
}

用eval容易被注入代碼

看看這段代碼,你只想賦值告喊,彈出了對話框

workers.assignment("1","';alert('xiaohu');'");

在看看用eval解析json字符串的用法麸拄。同樣這樣也會讓人注入代碼,而且性能不好黔姜。

var jsonString='{"task":"write better javascript!"}';
var json = eval('('+jsonString+')');
console.log(json);

正確的做法應(yīng)該用專門解析json的函數(shù)或者第三方庫

console.log(JSON.parse(jsonString));

括號

條件判斷應(yīng)該加括號拢切,并且成對出現(xiàn),但是就是有人喜歡節(jié)省點秆吵,這樣真實坑死隊友啊淮椰。看看下面這樣的代碼

var isGoodCoder=false;
var salary=0,vacation=0;
if(isGoodCoder)
    salary=10000;
    vacation=30;

上面的vacation=30;已經(jīng)不在if的控制范圍里面了,好一些的寫法應(yīng)該這樣

if(isGoodCoder){
    salary=10000;
    vacation=30;
}else{
    salary=1000;
    vacation=5;
}

數(shù)字問題

精度問題

程序并不能精確的保存和運算浮點數(shù)(小數(shù))主穗。我們看看JS如何處理這種情況泻拦。

0.1 + 0.2
=>0.30000000000000004

可以看到多出了0.00000000000000004,如果我們要用==或者和別的數(shù)字做運輸忽媒,就會有問題争拐。使用toFixed保存精度。

(0.1 + 0.2).toFixed(1);
=>"0.3"

雖然toFixed處理了精度問題晦雨,但是卻返回了字符串陆错,還要用parseFloat處理一下

parseFloat((0.1 + 0.2).toFixed(1));

parseFloat,parseInt可以從字符串中解析出數(shù)字。不過只能解析出以數(shù)字開頭的字符串金赦。
看一下下面的代碼音瓷。

parseFloat("2.333是xiaohu的零用錢");//=>2.333
parseFloat("xiaohu的零用錢為2.333");//=>NaN

進制轉(zhuǎn)換

parseInt(string, radix);

radix
一個2到36之間的整數(shù)值,用于指定轉(zhuǎn)換中采用的基數(shù)夹抗。比如參數(shù)"10"表示使用我們通常使用的十進制數(shù)值系統(tǒng)绳慎。總是指定該參數(shù)可以消除閱讀該代碼時的困惑并且保證轉(zhuǎn)換結(jié)果可預(yù)測漠烧。當忽略該參數(shù)時杏愤,不同的實現(xiàn)環(huán)境可能產(chǎn)生不同的結(jié)果。

看看如下代碼:

parseInt(021);//=>17已脓,八進制2*8^1+1*8^0=17
parseInt(021,10);//=>17珊楼,貌似第一個參數(shù)指定了進制,第二個參數(shù)沒啥用處度液?
parseInt("021");//老得js標志和新的標準不一樣厕宗,新的標準會返回21
parseInt("021",10);//=>21,這種方式才是最安全堕担。

parseInt("021",10);是最好的已慢。

判斷是否是數(shù)字

typeof data === "number"可以判斷一個變量是否是number類型。好像情況已經(jīng)很簡單了霹购。但是JS有一個NaN佑惠,表示不是一個數(shù)字。但是typeof NaN === "number"卻返回true齐疙。所以我們最好使用下面這個代碼判斷是否是數(shù)字膜楷,來處理這個特殊情況。

function isNumber(data){
    return ( typeof data === "number" 
        && !isNaN(data) ); 
}

強制轉(zhuǎn)換

var hasAge = !!age;  

這為啥要寫2個‘贞奋!’ 赌厅?
實際上!!age === Boolean(age),所以!!相當于強制轉(zhuǎn)換成Boolean類型了忆矛。
另外這樣也可以強制轉(zhuǎn)換

var a = '12';
//+a就是數(shù)字12.

想了解強制轉(zhuǎn)換的更多細節(jié)可以查看Javascript 強制類型轉(zhuǎn)換函數(shù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末察蹲,一起剝皮案震驚了整個濱河市请垛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌洽议,老刑警劉巖宗收,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異亚兄,居然都是意外死亡混稽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門审胚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匈勋,“玉大人,你說我怎么就攤上這事膳叨∏⒔啵” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵菲嘴,是天一觀的道長饿自。 經(jīng)常有香客問我,道長龄坪,這世上最難降的妖魔是什么昭雌? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮健田,結(jié)果婚禮上烛卧,老公的妹妹穿的比我還像新娘。我一直安慰自己妓局,他們只是感情好总放,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著跟磨,像睡著了一般间聊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抵拘,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音型豁,去河邊找鬼僵蛛。 笑死,一個胖子當著我的面吹牛迎变,可吹牛的內(nèi)容都是我干的充尉。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼衣形,長吁一口氣:“原來是場噩夢啊……” “哼驼侠!你這毒婦竟也來了姿鸿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤倒源,失蹤者是張志新(化名)和其女友劉穎苛预,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笋熬,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡热某,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了胳螟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昔馋。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖糖耸,靈堂內(nèi)的尸體忽然破棺而出秘遏,到底是詐尸還是另有隱情,我是刑警寧澤嘉竟,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布邦危,位于F島的核電站,受9級特大地震影響周拐,放射性物質(zhì)發(fā)生泄漏铡俐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一妥粟、第九天 我趴在偏房一處隱蔽的房頂上張望审丘。 院中可真熱鬧,春花似錦勾给、人聲如沸滩报。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脓钾。三九已至,卻和暖如春桩警,著一層夾襖步出監(jiān)牢的瞬間可训,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工捶枢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留握截,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓烂叔,卻偏偏與公主長得像谨胞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蒜鸡,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

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