摘要:大話先給大家意淫一下前端的目前的應(yīng)該是工業(yè)革命時(shí)代了。即在每個(gè)變量名前加上一個(gè)或多個(gè)字符表示相應(yīng)的類型。這對(duì)于大型查找是非常有好處的。當(dāng)然,一般的技術(shù)人員也不會(huì)手賤寫這么麻煩的。由于是弱類型的,所以可以直接使用或者進(jìn)行連續(xù)賦值。
大話js
先給大家意淫一下前端的futrue.
目前的JS應(yīng)該是工業(yè)革命時(shí)代了。以前js就只是作為什么移動(dòng)一下圖片,更換一下背景顏色等, 比較廢的活. 但是現(xiàn)在h5,nodeJS,ECMA-6,gulp,grunt,webpack,react...等等各種框架,工具的出現(xiàn),基本上顛覆了js的角色。以前js就是作為一個(gè)配角,html+CSS才是主要的,現(xiàn)在,你說你寫網(wǎng)頁的不會(huì)用js,呵呵,U ~= 渣渣. 而且庸俗一點(diǎn)來說,現(xiàn)在前端的薪資range應(yīng)該是其他技術(shù)類職業(yè)變化最大的,年薪2w+ 到 200w+ 的都有。所以js對(duì)于前端來說莫過于一塊金子招牌,如果你js真的吃透了,相信你的路真的是太寬了~
意淫完畢,該談?wù)铝耍琂S最佳實(shí)踐應(yīng)該是很多地方都會(huì)提到的。我這里引用的是高級(jí)程序設(shè)計(jì)里面的內(nèi)容,如有出錯(cuò)的地方,歡迎糾正.
由于js是一門弱類型的語言,所以往往造成了類型的不清楚,有可能胡亂使用不同類型上的方法,導(dǎo)致出錯(cuò)。
所以,一般給js的變量加上一些類型注釋是很有好處的。 通常我們會(huì)缺少加注釋的動(dòng)力,這樣想吧,如果未來的某一天,你需要接手別人的項(xiàng)目的時(shí)候,而別人的項(xiàng)目里面一條注釋也沒有,你的想不想死。。。所以, 有因才有果,一個(gè)良好的注釋真的很有用.
var found = "s"; //"string" var abc = true; //boolean
這應(yīng)該算是一種簡單的吧
還有一種是匈牙利標(biāo)記法。即在每個(gè)變量名前加上一個(gè)或多個(gè)字符表示相應(yīng)的類型。
通常,"o"為對(duì)象,"s"為string,"b"為Boolean,"i"表示整數(shù),"a"表示數(shù)組等
var sName ="string";
但是由于看起來很丑,推薦只在函數(shù)參數(shù)里面使用就足夠了。
算法的復(fù)雜度這也是面試時(shí)候會(huì)常常問到的。
flag | name | description |
---|---|---|
O(1) | 常數(shù) | 表示不管有多少值,執(zhí)行的時(shí)間都是很定的。表示簡單值和存儲(chǔ)在變量中的值 |
O(log n) | 對(duì)數(shù) | 總的執(zhí)行時(shí)間和值的數(shù)量相關(guān),但完成算法不一定獲取每一個(gè)值,比如二分查找 |
O(n) | 線性 | 執(zhí)行時(shí)間和值的數(shù)量直接相關(guān).ex: 遍歷數(shù)組 |
O(n^2) | 平方 | 總執(zhí)行時(shí)間和數(shù)量有關(guān),每個(gè)值要獲取n次。ex: 插入排序 |
一個(gè)一個(gè)解釋:
O(1)表示你無論有多少值,獲取常量值的時(shí)間都一樣。
var value = 5; var num = value + 4; console.log(num);
上面的復(fù)雜度整體為1,因?yàn)檫@只是簡單的變量查找。 O(1)的操作還有,數(shù)組的讀取
var value = [1,2,3,4,5]; console.log(value[1]); //2
同樣也是1,不管你是多少次查找都一樣。
所以說算法復(fù)雜度為O(1)的情況:只有在獲取變量以及數(shù)組的時(shí)候
最常用的是在你進(jìn)行屬性查找的時(shí)候。因?yàn)椴檎覍傩缘臅r(shí)候,會(huì)遍歷所有的對(duì)象上的屬性,然后才返回。所以他的復(fù)雜度為O(n).
var obj = { name:"jimmy", age:19 }; console.log(obj.name);
上面訪問obj.name的屬性的復(fù)雜度為O(n).還有一個(gè)例子:
var name = window.location.href.substring(window.location.href.indexOf("."));
可以數(shù)一下,上面算法的復(fù)雜度為6個(gè)O(n)因?yàn)榇嬖诹?個(gè)"."進(jìn)行屬性訪問。這種情況下,可以優(yōu)化一下,使用變量進(jìn)行保存,要知道變量始終是O(1)的
var href = window.location.href; var name = href.substring(href.indexOf("."));
上面就縮減到了4次".",節(jié)約了33%的查詢成本。 這對(duì)于大型查找是非常有好處的。但是如果你只是一次兩次的查找,則使用變量和未使用變量是沒有差別的。
另外對(duì)于變量的復(fù)雜度和屬性的復(fù)雜度,一般來說,如果可以使用arr[xxx]形式的遍歷的話,最好使用。
//jquery對(duì)象---$val for(var i = 0;i<$val.length;i++){ $val.eq(i).html(); //輸出innerHTML } //優(yōu)化過后 for(var i in $val){ $val[i].innerHTML; //輸出的innerHTML }
-----------分割線----------
這里感謝@Dreamacro 童鞋的提醒。這里特此說明一下,在V8里面引擎對(duì)于對(duì)象屬性的查找其實(shí)是O(1)的操作。
(Ps:我操,你到底再說什么鬼)
其實(shí)在V8里面對(duì)于對(duì)象屬性的存儲(chǔ)同樣是散列hash,但是V8就是快,為了實(shí)現(xiàn)向java一樣的遍歷速度,于是做了一點(diǎn)改動(dòng)。在你每次新建屬性的時(shí)候,V8會(huì)使用hidden class,新建一份原來對(duì)象的Copy并且添加上新屬性。于是在你下次查找屬性的時(shí)候他都會(huì)直接從這個(gè)新建的Class info尋找。 如果你一不小心手賤使用了delete的話,你查找的復(fù)雜度便會(huì)退化為O(n).
參考: hidden Class, V8引擎對(duì)象優(yōu)化
關(guān)于O(log n)和 O(n^2),由于目前對(duì)算法不精通,還是別誤導(dǎo)人了。
循環(huán)優(yōu)化一個(gè)常見的循環(huán)
for(var i= 0 ;i這個(gè)循環(huán)可以,但是不是很高效,因?yàn)槊恳淮窝h(huán)你都會(huì)去調(diào)用一次nodelist.length這個(gè)值,造成了 nodelist.length * O(n)這樣一個(gè)復(fù)雜度. 優(yōu)化的辦法就是將length提出去
for(var i= 0,len = nodelist.length;i上面的循環(huán)的復(fù)雜度就變?yōu)?O(1) + 1O(n); 當(dāng)然上面那種簡單而且更高效.
但是試想一下,如果你在循環(huán)體還需要使用nodelist[i]for(var i= 0,len = nodelist.length;i想一想,nodelist[i]乍看起來并不是循環(huán)體內(nèi)所需要的。那我們應(yīng)該怎么做呢?
很簡單,利用null為false的條件自動(dòng)轉(zhuǎn)換for(var i = 0,node; node = nodelist[i++];){ node... } //當(dāng)然你也可以直接使用 for(var node of nodelit){ //這種方式更加方便簡潔,但是是es6的一個(gè)新特性 node ... }另外循壞可以通過以下幾個(gè)點(diǎn)來進(jìn)行優(yōu)化
1.減值迭代
2.簡化終止條件 3.簡化循環(huán)體 4.使用后測試循環(huán)--for和while都是前測試循環(huán), do-while是后測試循環(huán)減值迭代
: 從最大值開始減值,而不是從最小值減值迭代。簡化終止條件
: 即就是想上面例子一樣,對(duì)終止條件寄存在變量當(dāng)中.簡化循環(huán)體
: 這應(yīng)該是一個(gè)復(fù)雜的活,簡單的就是把不需要參與循環(huán)的語句提出來使用后測試
: 這其實(shí)就是防止對(duì)空值進(jìn)行循環(huán)var len = nodelist.length, i = 0; if(len>0){ do{ ... }while(++i===len); }這一部分可以參考一下Naraku_的讀書筆記。
還有一個(gè)例子,是我在騰訊面試的時(shí)候遇到的。從一篇全英文的文章中找到頻率次數(shù)最高的單詞
這里是我寫的一部分代碼,可以看一看
Duff優(yōu)化
篩選單詞每次看的時(shí)候,都會(huì)被他的精髓刺瞎了我24K金鈦合金*眼.
將循環(huán)次數(shù)展開書寫
這是Andrew B.King 寫出的一個(gè)比較著名的Duff裝置.將do-while分成兩個(gè)多帶帶的循環(huán)。簡單易懂。var iter = Math.floor(values.length/8); var leftover = values.length%8; var i = 0; if(leftover>0){ do{ process(values[i++]); }while(--leftover>0); } do { process(values[i++]); //8次處理 process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); }while(--iter>0);感覺比一般的for循環(huán)更加復(fù)雜,沒錯(cuò)。Duff一般是用來處理比較多的循環(huán)次數(shù)的時(shí)候才會(huì)真正顯示他的效率。如果你使用的循環(huán)次數(shù)就50+。那使用for效率會(huì)更高一點(diǎn). 通常我們前端也用不到,因?yàn)門M這是給后端用的。
避免雙重解釋這種情況一般只會(huì)發(fā)生在3種情況下, 即使用eval,Function,setTimeout里面.
eval("alert("hehe")"); var sayHi = new Function("alert("hehe")"); setTimeout("alert("hehe")",500);以上3中會(huì)發(fā)生雙重解釋,原因是,原本的js解析器不能直接解析上面的string字符串,需要額外新開一個(gè)解析器來進(jìn)行解釋,導(dǎo)致的結(jié)果就是速度被拖屎了。 當(dāng)然,一般的技術(shù)人員也不會(huì)手賤寫這么麻煩的。
修改alert("hehe"); var sayHi = function(){alert("hehe")} setTimeout(function(){alert("hehe")},500);這樣寫就沒什么問題了。
最小化語句即就是整合語句了。由于js是弱類型的,所以可以直接使用var或者let進(jìn)行連續(xù)賦值。而且這也是JIT編譯器幫你干的事.(JIT是一種能讓你代碼越運(yùn)行越快的編譯器)
//用了5條語句聲明5個(gè)變量 var count = 5; var color = "red"; var values = [1,2,3]; var now = new Date(); //用了1條語句聲明5個(gè)變量,注意每個(gè)變量用逗號(hào)隔開 var count = 5, color = "red", values = [1,2,3], now = new Date();還有就是使用數(shù)組和對(duì)象字面量
: 因?yàn)檎Z句量減少,解析器的壓力也減小了// 創(chuàng)建兩個(gè)對(duì)象 ----不好的方式 //one 四條語句 var values = new Array(); values[0] = 123; values[1] = 456; values[2] = 789; //two 四條語句 var person = new Object(); person.name = "jozo"; person.age = 21; person.sayName = function(){ alert(this.name); }; // 創(chuàng)建兩個(gè)對(duì)象 ----推薦的方式 //one 1條語句 var values = [123,456,789] //two 1條語句 var person = { name : "jozo", age : 21, sayName : function(){ alert(this.name); };總的來說, js優(yōu)化之路漫漫,沒有年年月月的積累,是不可能達(dá)到什么特別高的level的。所以說,活到老學(xué)到老,這是永恒的真理~~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/78421.html
摘要:我的是忙碌的一年,從年初備戰(zhàn)實(shí)習(xí)春招,年三十都在死磕源碼,三月份經(jīng)歷了阿里五次面試,四月順利收到實(shí)習(xí)。因?yàn)槲倚睦砗芮宄业哪繕?biāo)是阿里。所以在收到阿里之后的那晚,我重新規(guī)劃了接下來的學(xué)習(xí)計(jì)劃,將我的短期目標(biāo)更新成拿下阿里轉(zhuǎn)正。 我的2017是忙碌的一年,從年初備戰(zhàn)實(shí)習(xí)春招,年三十都在死磕JDK源碼,三月份經(jīng)歷了阿里五次面試,四月順利收到實(shí)習(xí)offer。然后五月懷著忐忑的心情開始了螞蟻金...
摘要:前言在編程藝術(shù)中初步實(shí)現(xiàn)的圖片庫的總結(jié)一中,有很多不足之處比如事件處理嵌套在中,顯得如此笨重和屌絲沒有對(duì)函數(shù)進(jìn)行相應(yīng)的安全檢查等,本篇文章對(duì)上述問題做了全面的升級(jí)。 前言:在《DOM編程藝術(shù)》中初步實(shí)現(xiàn)的圖片庫的總結(jié)(一)中,有很多不足之處:比如事件處理嵌套在HTML中,顯得如此笨重和屌絲;沒有對(duì)showPic函數(shù)進(jìn)行相應(yīng)的安全檢查等,本篇文章對(duì)上述問題做了全面的升級(jí)。--------...
摘要:項(xiàng)目中文字由進(jìn)行渲染。待觸發(fā)時(shí),取消中文輸入標(biāo)記,將文字渲染到上。而其中一些有趣的細(xì)節(jié)實(shí)現(xiàn)如文本渲染,對(duì)中文筆畫分割實(shí)現(xiàn)有趣的動(dòng)畫等并沒有描寫。 導(dǎo)言 目前富文本編輯器的實(shí)現(xiàn)主要有兩種技術(shù)方案:一個(gè)是利用contenteditable屬性直接對(duì)html元素進(jìn)行編輯,如draft.js;另一種是代理textarea + 自定義div + 模擬光標(biāo)實(shí)現(xiàn)。對(duì)于類似word的經(jīng)典富文本編輯器,...
摘要:在之前的文章中學(xué)習(xí)了關(guān)鍵字,可以保證變量在線程間的可見性,但他不能真正的保證線程安全。線程執(zhí)行到指令時(shí),將會(huì)嘗試獲取對(duì)象所對(duì)應(yīng)的的所有權(quán),即嘗試獲得對(duì)象的鎖。從可見性上來說,線程通過持有鎖的方式獲取變量的最新值。 在之前的文章中學(xué)習(xí)了volatile關(guān)鍵字,volatile可以保證變量在線程間的可見性,但他不能真正的保證線程安全。 /** * @author cenkailun *...
摘要:開放封閉原則應(yīng)該算是這幾個(gè)原則里面最容易理解的一個(gè)。另外,語句就是開放封閉原則的死敵這個(gè)是狀態(tài)模式中的一個(gè)例子。處理開放封閉模式的特例我們都是人,不可能一開始都寫出完美的代碼。 開放-封閉原則應(yīng)該算是這幾個(gè)原則里面最容易理解的一個(gè)。它的宗旨就是:如果你想擴(kuò)展或者改變一個(gè)程序的功能,可以增加代碼,但是不能改變程序的源碼。如果,是對(duì)于那些碼農(nóng)來說,最快捷的辦法就是改變?cè)创a,但是我們面向的是...
閱讀 2579·2023-04-26 03:00
閱讀 1392·2021-10-12 10:12
閱讀 4190·2021-09-22 15:33
閱讀 2908·2021-09-22 15:06
閱讀 1530·2019-08-30 15:44
閱讀 2145·2019-08-30 13:59
閱讀 534·2019-08-30 11:24
閱讀 2407·2019-08-29 17:07