2011-04-09 26 views
0

是否存在檢查代碼中的所有參數和其他條件,如果我知道,我從來沒有通過錯誤的參數,它應該工作正常(說我已經做了一些檢查之外的代碼)。在內部使用的代碼中製作額外的代碼是否是一種好的做法?

例子:

驗證碼:

/** 
* Applies function to all elements of array in specified 
* context. 
* If array is empty, returns null. 
*/ 
MyNameSpace.foreach = function(arr, callback, context) { 
    if (!(arr instanceof Array)) { 
     throw new Error('first argument is not an array'); 
    } 
    if (typeof callback !== 'function') { 
     throw new Error('callback is not a function'); 
    } 
    if (typeof arr.length === 'undefined') { 
     throw new Error('Length undefined'); 
    } 

    var con = typeof context === 'object' ? context : window; 

    var i = arr.length; 
    if (i <= 0) { 
     return null; 
    } 

    for (j = 0; j < i; j++) { 
     callback.call(con, j, arr[j]); 
    } 
} 

可能是:

MyNameSpace.foreach = function(arr, callback, context) { 
    var con = typeof context === 'object' ? context : window; 

    var i = arr.length; 
    if (i <= 0) { 
     return null; 
    } 

    for (j = 0; j < i; j++) { 
     callback.call(con, j, arr[j]); 
    } 
} 

回答

1

但如果你把它在生產中啓用這些信息可能會執行的一點,你可以用一個類型檢查庫,無論是在生產還是在調試過程中:

function TypeEnforce (func, ctx, config) { 
    if (!(this instanceof TypeEnforce)) { 
     return new TypeEnforce(func, ctx); 
    } 
    if (typeof func === 'string' && ctx) { 
     this.funcString = func; 
     func = ctx[func]; 
    } 
    this.ctx = ctx; 
    this.autoset = config && config.autoset; 
    this.oldFunc = func; 
} 
TypeEnforce.prototype.argTypes = function (args) { 
    var that = this; 
    this.reqArgTypesFunc = function() { 
     for (var i=0, argl = args.length; i < argl; i++) { 
      if (
       (args[i] === 'Array' && Object.prototype.toString.call(arguments[i]) !== '[object Array]') || 
       (args[i] !== 'Array' && typeof arguments[i] !== args[i]) 
      ) { 
       throw 'Argument ' + i + ' [' + arguments[i] + '] should be of type ' + args[i]; 
      } 
     } 
     that.oldFunc.apply(that.ctx, arguments); 
    }; 
    if (this.autoset) { 
     this.ctx[this.funcString] = this.reqArgTypesFunc; 
    } 
    return this; 
}; 
TypeEnforce.prototype.props = function (props) { 
    var that = this; 
    this.reqPropsFunc = function() { 
     for (var p in props) { 
      if (typeof arguments[p][props[p]] === 'undefined') { 
       throw 'The property "' + props[p] + '" of argument no. ' + p + 
         ' [' + arguments[p] + '] should not be undefined'; 
      } 
     } 
     var method = that.reqArgTypesFunc || that.oldFunc; 
     method.apply(that.ctx, arguments); 
    }; 
    if (this.autoset) { 
     this.ctx[this.funcString] = this.reqPropsFunc; 
    } 
    return this; 
}; 
TypeEnforce.prototype.get = function (props) { 
    return this.reqPropsFunc || this.reqArgTypesFunc || this.oldFunc; 
}; 

...你的情況,你可能這使用方法如下:

if (!MyNameSpace) { 
    var MyNameSpace = {}; 
} 
MyNameSpace.foreach = function(arr, callback, context) { 
    var con = typeof context === 'object' ? context : window; 

    var i = arr.length; 
    if (i <= 0) { 
     return null; 
    } 

    for (j = 0; j < i; j++) { 
     callback.call(con, j, arr[j]); 
    } 
}; 

TypeEnforce('foreach', MyNameSpace, {autoset:true}). 
    argTypes(['Array', 'function']). 
    props({0:'length'}); 

MyNameSpace.foreach(['a', 'b'], function (k, v) { 
    alert(k+':'+v); 
}); 

通過這種方法,你可以分離出難看的類型檢查代碼,甚至禁用它,如果你只是在測試過程中需要它。您可以進一步添加用於參數或屬性值檢查的方法。

3

當然也可以是很好的做法。它可以幫助您的應用程序的穩定性,並幫助調試。缺點是它可能會混淆代碼(使其難以閱讀),並且可能會影響性能(儘管大多數JavaScript應用程序的性能並不重要)。

你必須在每種情況下采取一種觀點。這實際上取決於:(1)參數有可能不正確;(2)如果它們的確會造成多大的傷害。

1

軟件涉及測試輸入和輸出時的一般原則是:「對輸入靈活,對輸出嚴格。」你應該總是對你的輸入進行額外的檢查,這樣如果你的方法得到了預期的結果,你的代碼就不會中斷。

1

這絕對是一種好的做法,因爲任何使用您的類或函數的代碼都可能會在不知不覺中傳遞可能導致代碼崩潰的值。例如:程序員偶然向我的代碼發送了一個NULL指針,該代碼必須對指針指向的對象進行深層複製。
但是由於我在複製構造函數的初始化列表中克隆了指向實例的實例,因此沒有人能夠找出程序崩潰的原因。
程序員說我應該保留一個NULL指針的檢查,但最終我們決定繼續檢查他的最終結果,因爲我們需要通過初始化列表來保持複製的效率,而這更快。

所以你可以決定取決於:
1.使用copy-ctor初始化列表的效率。
2.您如何記錄輸入參數和您的函數/類的限制。
3.您的代碼是否可能因爲惡意輸入而導致崩潰/安全問題
4.您的軟件需要什麼樣的異常處理。

相關問題