一级日韩免费大片,亚洲一区二区三区高清,性欧美乱妇高清come,久久婷婷国产麻豆91天堂,亚洲av无码a片在线观看

高效編寫(xiě)JavaScript代碼的技巧

時(shí)間:2024-08-25 02:10:08 JavaScript 我要投稿
  • 相關(guān)推薦

高效編寫(xiě)JavaScript代碼的技巧

  如何能高效的編寫(xiě)出優(yōu)秀的JavaScript代碼,有哪些技巧?下面YJBYS小編為你介紹!

  原則

  不要做任何優(yōu)化除非的確需要優(yōu)化

  任何的性能優(yōu)化都必須以測量數據為基礎,如果你懷疑代碼存在性能問(wèn)題,首先通過(guò)測試來(lái)驗證你的想法。

  性能優(yōu)化三問(wèn)

  我還能做哪些工作從而讓代碼變得更有效率?

  流行的JavaScript引擎通常會(huì )做哪些優(yōu)化工作?

  哪些優(yōu)化是JavaScript引擎不能做的,垃圾回收器是否能清理我們期望清理的?

  對JavaScript引擎的深入了解有助于我們編寫(xiě)高效的JavaScript代碼,但不要只針對某一特定引擎做性能優(yōu)化。

  V8的幾個(gè)關(guān)鍵概念

  基礎編譯器,解析你的JavaScript代碼并生成Native Machine Code執行,而不是執行字節碼或是直接對JavaScript解釋執行。

  在V8中,對象以object model的形式存在。對象在JavaScript中是以關(guān)聯(lián)數組的形式存在,但V8采用的是Hidden

  Classes——一種對查找操作進(jìn)行了優(yōu)化的內部類(lèi)型系統。

  運行時(shí)探查器監視運行中的系統,并識別出Hot functions,即是耗用了較長(cháng)時(shí)間的代碼

  優(yōu)化編譯器重新編譯并優(yōu)化由運行時(shí)探查器識別出來(lái)的Hot代碼

  V8支持反優(yōu)化,優(yōu)化編譯器能夠發(fā)現過(guò)度優(yōu)化的代碼并對其進(jìn)行處理

  V8有自己的垃圾回收器

  垃圾回收垃圾回收是一種內存管理機制,垃圾回收器會(huì )嘗試清理掉不再被使用的對象,并回收內存。

  在絕大多數情況下都不需要手動(dòng)解除引用

  你不可能強制垃圾回收器工作

  刪除引用的誤區

  盡可能不要使用delete,在下面的列子中,delete 帶來(lái)的弊遠遠大于利

  var o = { x: 1};delete o.x;

  主要的原因是為了避免在運行時(shí)修改Hot對象的結構,因為固定的對象結構有助于JavaScript引擎對其進(jìn)行優(yōu)化,而delete會(huì )導致對象結構改變。

  另外一個(gè)誤區是將對象設置為null,將對象設置為null不會(huì )刪除對象,只是將對象指向null,這要好過(guò)采用delete,但通常也是不必要的。

  全局變量在整個(gè)頁(yè)面生命周期中都是不會(huì )被清理的,無(wú)論頁(yè)面打開(kāi)多長(cháng)時(shí)間,除非是刷新頁(yè)面或者轉到其他頁(yè)面。局部變量(Function-scoped)在方法執行完后,且沒(méi)有被引用的情況下將會(huì )被回收。

  所以,請盡量避免使用全局變量。

  經(jīng)驗法則為了使垃圾回收器盡早回收對象,不要保持不必要的對象引用。

  比手動(dòng)解除引用更好的方法是將對象放在合適的變量域中,能用局部變量就不要采用全局變量

  當事件監聽(tīng)不再需要時(shí),請解除事件綁定,尤其是當事件綁定的DOM對象被刪除時(shí)

  如果有使用本地緩存,請確保有合適的清理機制(比如時(shí)效機制),從而避免大量無(wú)用的數據存儲。

  方法 (Function)

  如前面所說(shuō),垃圾回收器只有在對象不可觸及的時(shí)候才會(huì )對其做回收處理?紤]如下兩個(gè)列子:

  function foo(){

  var bar = new LargeObject()

  bar.someCall();}

  function foo(){

  var bar = new LargeObject()

  bar.someCall();

  return bar;}var b = foo();

  在第一個(gè)例子中,bar指向的對象會(huì )在方法執行完畢后處于可回收狀態(tài);在第二個(gè)列子中,由于在局部變量外維護了一個(gè)全局變量b,bar指向的對象無(wú)法被回收。

  閉包 (Closures)

  當一個(gè)方法返回一個(gè)內部方法時(shí),被返回的內部方法能訪(fǎng)問(wèn)外部方法的局部變量域即使外部方法已經(jīng)執行完畢。

  function sum(x){

  function sumIt(y){

  return x + y;

  }}var sumA = sum(4);var sumB = sumA(3);

  在上面的例子中,sumIt方法即使處于sum的局部變量域中,但由于存在一個(gè)sumA全局變量,在sum執行完畢后也無(wú)法被回收。再看兩個(gè)例子

  var a = function(){

  var largeObj = new LargeObject();

  return function(){

  return largeObj;

  }}();var a = function(){

  var smallObj = new SmallObj();

  var largeObj = new LargeObj();

  return function(n){

  return smallObj;

  }}();

  第一個(gè)例子中,largeObj可以通過(guò)變量a訪(fǎng)問(wèn),因此不可被回收;在第二個(gè)例子中,方法一旦執行完畢,largeObj就無(wú)法被訪(fǎng)問(wèn)了,因此處于可回收狀態(tài)。

  定時(shí)器 (Timer)在setTimeout / setInterval方法中的引用,只有當定時(shí)器執行完成后才能被回收。

  V8優(yōu)化小貼士

  某些行為會(huì )導致V8停止優(yōu)化工作,比如try-catch,為了能弄清哪些代碼可以被優(yōu)化,哪些不能,你可以在V8命令行工具中使用—trace-opt file.js獲得有用的信息。

  如果你在意速度,那就盡可能保證你的方法是”單形的(monomophic)"

  不要做類(lèi)似如下的嘗試

  function add(x, y){

  return x+y;}add(1,2);add('a','b');add(my_custom_object, undefined);

  不要加載沒(méi)有被初始化或者已被刪除的元素,盡管在輸出上沒(méi)有不同,但卻會(huì )讓代碼變得更慢

  不要寫(xiě)大方法,因為他們很難被優(yōu)化。

  對象還是數組, 如何選擇?

  如果存儲的是大量數字,或者是相同類(lèi)型的對象列表,采用數組;

  如果根據語(yǔ)義你需要一個(gè)有很多屬性的對象,那就采用對象,在內存利用方面這會(huì )很高效,同時(shí)也很快;

  無(wú)論是數組還是對象,采用整數索引都最快的。

  var sum = 0;for (var x=0; x

  sum + = arr[x].payload;}

  var sum = 0;for(var x in obj){

  sum += obj[x].payload;}

  var sum = 0;for(var x=0; x<1000,++x){

  sum += obj[x].payload;}

  var sum = 0;var keys = Objects.keys(obj);for(var x=0; x

  sum += obj[keys[x]].payload;}

  在上面的四段代碼中,第一段和第三段速度比第二段和第四段要快很多。其中,第一段代碼執行最快,最后一段代碼執行最慢。

  相比數組中的元素,對象的屬性在結構上相對復雜。在引擎層面,內存中越是簡(jiǎn)單的結構越容易被優(yōu)化,尤其是包含數字的數組。因此,如果你需要向量,采用數組而不是一個(gè)包含x,y, z屬性的對象會(huì )有更優(yōu)的性能表現。

  在JavaScript中,數組和對象最重要的不同是數組的length屬性,如果你能自己維護這個(gè)值,對象在V8中也能跑出數組的速度。

  使用對象的性能小貼士

  使用構造函數創(chuàng )建對象,因為所有采用同一構造函數創(chuàng )建的對象都具有相同的hidden class,另外,采用構造函數創(chuàng )建對象也比Object.create()這種方法略塊。

  盡管JavaScript沒(méi)有限制類(lèi)型數量和對象的復雜度,但長(cháng)原型鏈和大量的對象屬性會(huì )對性能造成損害。因此盡可能保持較短的原型鏈和較少的對象屬性。

  對象的拷貝for..in循環(huán)是性能殺手,通過(guò)該方法遍歷對象屬性進(jìn)行拷貝非常低效?截惔髮ο笫冀K會(huì )降低性能,盡可能不要干這樣的事情,當然大對象的存在本身就是一個(gè)錯誤。如果你確實(shí)需要在性能攸關(guān)的代碼中拷貝對象,可以采用如下的方式。

  function clone(original){

  this.foo = original.foo;

  this.bar = original.bar;}var copy = new clone(original);

  緩存采用模塊化編程(Module Pattern)的方法

  // prototypalKlass1 = function(){}Klass1.prototype.foo = function(){

  log('foo');}Klass1.prototype.bar = function(){

  log('bar');}

  // Module patternKlass2 = function(){

  var foo = function(){

  log('foo');

  }

  var bar = function(){

  log('bar');

  }

  return {foo:foo,bar:bar}}

  // Module pattern with cached functionsvar fooFn = function(){

  log('foo');}var barFn = function(){

  log('bar')}Klass3 = function(){

  return{

  foo: fooFn,

  bar: barFn }}

  執行速度從快到慢依次是

  Module Pattern with Cached functions → prototypal → Module pattern

  使用數組的性能小貼士

  不要刪除數組元素,當數組的Key set分布分散后,V8會(huì )將存儲方式轉為字典,導致速度變慢。

  數組常量更高效,尤其是小數組和中等大小的數組。

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

  var a = [];for(var i=1, i<=4; i++){

  a.push(i);}

  不要采用第二段代碼中的方法初始化數組。

  不要在數組中存儲不同類(lèi)型的元素

  V8中,稀疏數組( Sparse Arrays)是被當成字典對待的,因此相比密集數組(Full Arrays),執行速度更慢

  與緊湊的數組相比,滿(mǎn)身是洞的數組執行更慢,即使是從密集數組中刪除一個(gè)元素,也會(huì )帶來(lái)性能上的損失。

  不要預先給大數組(大于64k)分配一個(gè)最大值

  var arr = [];for(var i = 0; i< 1000000; i++){

  arr[i] = 1;}

  var arr = new Array(1000000);for(var i=0; i<1000000; i++){

  arr[i]=i;}

  需要注意的是,不同引擎在這一點(diǎn)上有不同,在Nitro(Safari)中,第二段代碼跑得更快,但在V8(Chrome), SpiderMonkey(Firefox)中,第一段更快。

【高效編寫(xiě)JavaScript代碼的技巧】相關(guān)文章:

在Java中執行JavaScript代碼04-01

JavaScript實(shí)現網(wǎng)頁(yè)刷新代碼段03-25

常用排序算法之JavaScript實(shí)現代碼段03-10

網(wǎng)頁(yè)程序設計之實(shí)用JavaScript代碼段03-06

如何讓JAVA代碼更高效03-20

關(guān)jQuery彈出窗口簡(jiǎn)單實(shí)現代碼-javascript編程03-30

J2EE項目代碼編寫(xiě)規范01-23

javascript中for/in循環(huán)以及常見(jiàn)的使用技巧04-02

高效溝通的技巧02-26

一级日韩免费大片,亚洲一区二区三区高清,性欧美乱妇高清come,久久婷婷国产麻豆91天堂,亚洲av无码a片在线观看