2014-11-25 79 views
0

我想在JavaScript中將「基」類型的屬性和初始化邏輯包含到「子」類型中。以下是習慣用語嗎?將基類型的屬性應用於JavaScript中的子類型

function Base(arg1) { 
    this.foo = arg1.foo; 
} 

function Sub(arg1) { 
    //Initialize using the base ctor... 
    Base.call(this, arg1); 
} 
+0

所以,當有人做'變種x =新的子( 'ABC')'你想要的'x.foo == ='abc''? – deitch 2014-11-25 10:03:02

+0

是的,這是可能的方法之一。只是當Sub實例被實例化時Base函數被調用的缺點。 – dfsq 2014-11-25 10:03:04

+0

@deitch是的,我想初始化邏輯在基地,初始化子類型時運行 – Ben 2014-11-25 10:04:16

回答

2

是(只是this.foo = arg1Base,不arg1.foo),這就是你設置了JavaScript的原型繼承和構造函數基礎/派生關係的典型方式。下面是完整的模式:

function Base(arg1) { 
 
    this.foo = arg1; 
 
} 
 
Base.prototype.doSomething = function() { 
 
    snippet.log("doSomething says foo is " + this.foo); 
 
}; 
 

 
function Sub(arg1) { 
 
    //Initialize using the base ctor... 
 
    Base.call(this, arg1); 
 
} 
 
Sub.prototype = Object.create(Base.prototype); 
 
Sub.prototype.constructor = Sub; 
 
Sub.prototype.doSomethingElse = function() { 
 
    snippet.log("doSomethingElse says foo is " + this.foo); 
 
}; 
 

 
// Usage 
 
var s = new Sub('bar'); 
 
snippet.log("s.foo = " + s.foo); 
 
s.doSomething(); 
 
s.doSomethingElse();
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

我有一個腳本,Lineage,這使得它更具聲明,鼓勵私人資源,並使得父叫「類」的方法更容易。但是這個腳本將會被ES6的類所淘汰,儘管被稱爲類仍然是原型的。 (並且ES6的類語法的轉譯器生成ES5代碼,因此您現在可以使用新的語法,這意味着在使用結果之前需要構建步驟。)

如果您需要支持真正的舊瀏覽器(像IE8)沒有Object.create,你可以墊片上面使用它的一個參數版本:

if (!Object.create) { 
    Object.create = function(proto, props) { 
     if (typeof props !== "undefined") { 
      throw "The second argument of Object.create cannot be shimmed."; 
     } 
     function ctor() { } 
     ctor.prototype = proto; 
     return new ctor(); 
    }; 
} 

注意,構造函數只是一個方式,你可以在JavaScript中使用原型繼承,不是唯一的方法。但是如果你使用構造函數,那就是模式。

+0

正在使用其他構造函數進行初始化,但沒有修改原型鏈仍然慣用? – Ben 2014-11-25 10:17:43

+0

@Ben:我沒有看到它完成,沒有。因爲'Base'是一個構造函數(由大寫'B'表示),理論上它可以依賴於原型上的某些東西,如果你沒有建立關係,它就會分配給那些不在那裏的實例。當然,如果你寫了他們兩個,你知道它不會那樣做,但我會說在那個時候這不是真正的習慣。可能更好地將一個函數附加到'Base'(比如'Base.setup = function(obj,arg1){...};'),然後在'Sub'中使用'Base.setup(this,arg1)'。這樣很明顯'obj'可能是任何東西。 ('Base'也會這樣做,用於代碼重用。) – 2014-11-25 10:30:30

0

有多種方式可以這樣做:

//Local 
function fn() 
    { 
    var foo = []; 
    foo.toUpperCase = String(foo).toUpperCase; 
    foo.push("a"); 
    foo.toUpperCase(); 
    } 
fn(); 

//Global 
foo = []; 
window.toUpperCase = function (obj) {return String(obj).toUpperCase();} 
foo.push("a"); 
toUpperCase(foo); 

//Prototype 
foo = []; 
Array.prototype.toUpperCase = String.prototype.toUpperCase; 
foo.push("a"); 
foo.toUpperCase(); 

//Constructor Prototype 
foo = []; 
Array.prototype.constructor = String.prototype.toUpperCase; 
foo.push("a"); 
foo.constructor(); 

//toString override 
foo = []; 
foo.push("a"); 
var bar = String(foo); 
foo.toString = function() { return bar.toUpperCase(); } 
foo.toString(); 

內置Error對象使用下列成語:

  • 方法

    全球Error對象不包含但是,它自己的方法通過原型鏈繼承了一些方法。

  • 錯誤實例

    所有的錯誤實例和非一般錯誤的情況下,從Error.prototype繼承。與所有構造函數一樣,您可以使用構造函數的原型來爲使用該構造函數創建的所有實例添加屬性或方法。

  • 錯誤類型

    除了一般性錯誤的構造,還有其他六個核心錯誤的構造函數中的JavaScript:

    1. 的EvalError

      創建一個實例代表一個錯誤,即oc詛咒全局函數eval()。

    2. 的RangeError

      創建表示當一個數值變量或參數是其有效範圍之外時發生的錯誤的實例。

    3. 的ReferenceError

      創建表示時發生解引用的無效引用的錯誤的實例。

    4. 的SyntaxError

      創建一個表示的是,雖然在解析代碼的eval()發生了語法錯誤的實例。

    5. 類型錯誤

      創建表示當一個變量或參數是有效類型的不是發生錯誤的實例。

    6. 的URIError

      創建時是encodeURI()或decodeURI()被傳遞的參數無效時發生表示錯誤的實例。

參考