私はJavaScriptに比較的慣れておらず、使用しているサードパーティのライブラリに.extendと.prototypeが表示され続けています。Prototype javascriptライブラリと関係があると思いましたが、そうではないと思い始めています。これらは何に使用されますか?
7 に答える
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などのライブラリによって提供されます。
.extend()
は、他のオブジェクトからオブジェクトを簡単に作成できるようにするために、多くのサードパーティ ライブラリによって追加されています。いくつかの例については、 http://api.jquery.com/jQuery.extend/またはhttp://www.prototypejs.org/api/object/extendを参照してください。
.prototype
オブジェクトの「テンプレート」(そう呼びたい場合)を参照するため、オブジェクトのプロトタイプにメソッドを追加することにより(これはライブラリで多く見られ、String、Date、Math、さらにはFunctionに追加されます)それらのメソッドそのオブジェクトのすべての新しいインスタンスに追加されます。
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 言語の奇妙なケース」と言えます。
基本クラスがあり、基本クラスを拡張して継承のような機能を取得するという考え方です (完全ではありませんが)。
全体的なアイデアは、プロトタイプが実際に意味するものを取得することです。jQuery.extend
John Resig のコード (実際のものに近い) がそれを行うコード チャンクを書き、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 Inheritance を参照してください。