回答:
Javascriptの継承はプロトタイプベースであるため、Date、Mathなどのオブジェクトのプロトタイプ、さらには独自のカスタムプロトタイプまで拡張できます。
Date.prototype.lol = function() {
alert('hi');
};
( new Date ).lol() // alert message
上のスニペットでは、すべての Dateオブジェクト(既存のオブジェクトとすべての新しいオブジェクト)のメソッドを定義しています。
extend
通常は、基本クラスから拡張する新しいサブクラスのプロトタイプをコピーする高水準関数です。
だからあなたは次のようなことをすることができます:
extend( Fighter, Human )
そして、Fighter
コンストラクタ/オブジェクトのプロトタイプを継承しますHuman
あなたのようなメソッドを定義しそうならば、live
そしてdie
上Human
、その後Fighter
もこれらを継承します。
明確化の更新:
「高水準関数」は.extendが組み込まれていないことを意味しますが、jQueryやPrototypeなどのライブラリによって提供されることがよくあります。
changing the native objects can break other developer's assumptions of these objects,
追跡に多くの時間がかかることがあるjavascriptバグにつながるためです。この回答の最初の文は、この貴重なJavaScriptの実践を誤って説明しているようです。
.extend()
他のオブジェクトからオブジェクトを簡単に作成できるように、多くのサードパーティライブラリによって追加されます。いくつかの例については、http://api.jquery.com/jQuery.extend/またはhttp://www.prototypejs.org/api/object/extendを参照してください。
.prototype
オブジェクトの「テンプレート」(それを呼び出したい場合)を参照するため、オブジェクトのプロトタイプにメソッドを追加することにより(これらはライブラリに多く表示され、文字列、日付、数学、または関数にも追加されます)、これらのメソッドそのオブジェクトのすべての新しいインスタンスに追加されます。
extend
たとえばjQueryまたはPrototypeJSのメソッドは、ソースから宛先オブジェクトにすべてのプロパティをコピーします。
prototype
プロパティについては、関数オブジェクトのメンバーであり、言語コアの一部です。
新しいオブジェクトインスタンスを作成するために、任意の関数をコンストラクターとして使用できます。すべての関数にこのprototype
プロパティがあります。
new
関数オブジェクトで演算子を使用すると、新しいオブジェクトが作成され、そのコンストラクターから継承されますprototype
。
例えば:
function Foo () {
}
Foo.prototype.bar = true;
var foo = new Foo();
foo.bar; // true
foo instanceof Foo; // true
Foo.prototype.isPrototypeOf(foo); // true
JavaScriptの継承は、どこでも開かれた議論のようです。「Javascript言語の奇妙な事件」と言えます。
基本クラスがあり、それから基本クラスを拡張して継承のような機能を(完全ではないが)取得するという考え方です。
全体のアイデアは、プロトタイプが本当に意味するものを取得することです。John Resigのコード(何に近いかjQuery.extend
)がコードチャンクを書いて、base2とプロトタイプライブラリがインスピレーションの源であると彼が主張するまで、私はそれを理解しませんでした。
これがコードです。
/* Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
* MIT Licensed.
*/
// Inspired by base2 and Prototype
(function(){
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function(){};
// Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
return function() {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) :
prop[name];
}
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
// And make this class extendable
Class.extend = arguments.callee;
return Class;
};
})();
仕事をしている3つの部分があります。最初に、プロパティをループしてインスタンスに追加します。その後、後でオブジェクトに追加するためのコンストラクターを作成します。ここで、重要な行は次のとおりです。
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
まずClass.prototype
、目的のプロトタイプをポイントします。オブジェクト全体が変更されました。つまり、レイアウトを強制的に独自のレイアウトに戻す必要があります。
そして使用例:
var Car = Class.Extend({
setColor: function(clr){
color = clr;
}
});
var volvo = Car.Extend({
getColor: function () {
return color;
}
});
詳細については、John Resigの投稿によるJavaScriptの継承をご覧ください。
extend
サードパーティライブラリの一部の関数は、他の関数よりも複雑です。たとえば、Knockout.jsには、jQueryが行うチェックの一部を含まない、最小限のシンプルなものが含まれています。
function extend(target, source) {
if (source) {
for(var prop in source) {
if(source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
.extend
は組み込みではありませんが、jQueryやPrototypeなどのライブラリーによって提供されることがよくあります。