2014-01-14 91 views
1

我試圖確定一些JavaScript的性能影響。在我們的應用程序中,表單包含許多小部件。並非所有小部件都用於每個頁面,或者小部件可能會多次使用。我一直在思考類似以下的模型(請注意,實際的腳本是一個複雜得多,我已經簡化它是短暫的):在需要時創建JavaScript函數

var widget = { 
    type1: function(args) { 
     function getName() { 
      return this._name; 
     } 
     return (widget.type1 = function(args) { 
      return { 
       _name: args.name, 
       getName: getName 
      }; 
     })(args); 
    } 
} 

我的想法是,第一次widget.type1函數被調用,它將初始化widget.type1所需的所有代碼。任何後續的widget.type1將使用這些函數。我知道我可以做這樣的事情:

var widget = { 
    type1: function(args) { 
     return { 
      _name: args.name, 
      getName: function getName() { 
       return this._name; 
      } 
     }; 
    } 
} 

但隨後各TYPE1對象有它是做同樣的事情,我會假設會使用更多的內存功能的自己的副本(我已經測試過瀏覽器調試工具,即o1.getName!= o2.getName)。

我可以寫出當前頁面上來自服務器的小部件類型的腳本,但是我沒有從緩存單個js文件中受益,也不希望將每個小部件放入它自己的js文件,因爲那樣它將不得不單獨下載它們。

這會導致問題嗎?我認爲這樣做會/應該這樣嗎?其他想法?

編輯

我想我應該解釋一下我的推理。我的想法(可能是錯誤的)是,第一次使用小部件時,它會初始化小部件使用的邏輯。例如,如果我從來沒有創建一個type1小部件,則不需要爲type1小部件的原型添加一堆函數。我寫的代碼是高度簡化。這個小部件可能會有500多行代碼,我實際上並沒有使用getName函數,這只是一個例子。如果這個小部件沒有被使用,它根本就不需要這個邏輯。它還保持該部件僅在全局範圍外使用的功能。

我目前使用的對象和功能添加到該對象(例如MyType.prototype.whatever = function(){ ... })的原型,但一想到發生,我認爲,如果我從來沒有創建MyType對象,爲什麼還要初始化的MyType原型?

另一種方法來做我在想什麼,這次使用對象原型(再次,可能有300個函數添加到type1的原型。我問的想法是,如果它有任何意義,繼續前進,把它們添加到TYPE1的原型如果從未創建TYPE1):

var widget = { 
    _type1Init: function() 
    { 
     widget.type1.prototype.getName = function() { 
      return this._name; 
     } 
     widget._type1Init = function(){} //So calling again won't do anything. 
    }, 
    type1: function(args) { 
     widget._type1Init(); 
     this._name = args.name; 
    } 
} 
if(*someCondition*) 
    var obj = new widget.type1({ name: "hello world" }); // If an object is created, it gets initilized, otherwise it won't. 
+0

第二段代碼更好。你應該意識到你將會在這兩種情況下創建一個包裝'_name'的函數,但是在第二個函數中你有一個不需要的seaf,它不會完成任何事情(只要你做'widget.type1',你的'getName'幫助器就會被創建' – megawac

+0

如果你想要基於實例的代碼,你應該考慮構造函數,或者'Object.create()'和它的向後兼容的對象。 – PHPglue

+1

計算機有千兆字節的內存,擔心幾個字節是不值得的。並且易於維護更具價值。如果要在對象之間共享方法,請使用原型繼承。 – RobG

回答

0

也許你應該考慮:

function type1(argObj){ 
    // use arguments Array for all arguments - you have Object notation 
    this._name = argObj.name; 
    // not sure why you need this function 
    this.getName = function(){ 
    return this._name; 
    } 
} 
function widget(){ 
    this.type1 = type1; 
} 
0

我真的不知道你想要達到的目標,但我認爲這是一個案例prototype

var widget = { 
    type1: function(args) { 
     this._name = args.name; 
    } 
}; 

widget.type1.prototype.getName = function() { 
    return this._name; 
} 

var w1 = new widget.type1({ name: 'Alice' }); 
console.log(w1.getName()); 
var w2 = new widget.type1({ name: 'Bob' }); 
console.log(w2.getName()); 

JSFiddle

0

個人而言,我認爲...不一定是整個重組,但如果你的模塊/部件有:

一)已知的「私有靜態」功能(即要重用
二)必須在特定實例的狀態下操作功能的實用程序或無國籍變壓器)

然後你就進入了一個IIFE的市場。

{ 
    widget_1 : (function() { 
     var private_static_method = function (a, b, c) { 
      }; // no access to instance-based, closure state, unless passed as arguments 

     return function (d, e, f) { 
      // d, e and f are currently private, instance-based values (closure-scope) 
      this.public_method = function() { // this is copied per-instance 
       // has full access to d, e, f 
       return private_static_function(d, e, f); 
      }; 
      this.g = d; 
     }; 
    }()) 
} 

widget_1是返回的函數。 widget_1的構造函數現在擁有私有靜態訪問(閉包),無論是內部包裝函數,還是構造函數的外部。

所以只有一個副本,其中的靜態函數有沒有可以看到任何實例的任何私有狀態(閉包)。此外,進一步確保您可以將JS分解爲單獨的文件(您可以安全地將其重新構建到一個文件中),並讓對象在另一側以完全相同的方式工作。

// core-file.js 
var my_widgets = {}; 

// widget-1.js 
(function (core) { 
    var private_static_method = function() { }; 
    // ... 
    core.widget_1 = function (d, e, f) { }; 
}(my_widgets)); 

然後,您可以重新組合所有文件並像以前一樣在另一邊訪問它們。

var widget_1a = new my_widgets.widget_1(a, b, c); 

如果您有絕對沒有私有狀態,然後而不是「私有靜態」上面的東西,你可以在你的IIFE裏面做什麼是定義一個構造函數,並添加原型,它(這是「public-static」,沒有訪問私有狀態)。

widget_1 : (function() { 
    var Widget_1 = function (d, e, f) { this.g = d; }; 
    Widget_1.prototype.add_one = function() { this.g += 1; }; 
    return Widget_1; 
)()) 

var w1 = new my_widgets.widget_1(x, y, z); 
w1.add_one(); 
w1.g; // == x+1 

的封閉的實用功能,封閉組合每個實例的狀態,延長樣機的功能,等等,讓你做你想要的一切,從降低內存佔用空間(我希望你之前有成千上萬的這些擔心這一點),將超級安全(更高內存使用率)對象鏈接在一起。

雖然做着瘋狂的封閉的東西可能是安全的,世界之間的客戶端代碼(或,更特別是,在HTTP(S?)橋是非常不...

0

如果窗口小部件使用一次以上,比對象/原型模型將節省內存

是這樣的:

var wid = {} 

wid.objInit=function(p) { this.p=p } 
wid.objInit.prototype.doit=function(){ return this.p + ' it'} 

wid.init=function(arg){ 
    var w = new wid.objInit(arg) 
    return w 
} 

原型寫一次,放置到內存中一次,每個對象實例可以調用它。

var w = wid.init('do') 
console.log(w.doit()) 

var w2 = wid.init('do') 
console.log(w2.doit()) 
相關問題