Yanıtlar:
Javascript'in kalıtımı prototip tabanlıdır, bu nedenle Tarih, Matematik gibi nesnelerin prototiplerini ve hatta kendi özel olanlarınızı genişletirsiniz.
Date.prototype.lol = function() {
alert('hi');
};
( new Date ).lol() // alert message
Yukarıdaki kod parçacığında, tüm Date nesneleri (zaten mevcut olanlar ve tüm yenileri) için bir yöntem tanımlıyorum .
extend
genellikle temel sınıftan genişletmek istediğiniz yeni bir alt sınıfın prototipini kopyalayan yüksek düzeyli bir işlevdir.
Böylece şöyle bir şey yapabilirsiniz:
extend( Fighter, Human )
Ve Fighter
yapıcı / nesne prototipini miras alır Human
, bu nedenle live
ve die
on gibi yöntemleri tanımlarsanız , Human
o Fighter
zaman bunları da miras alır.
Güncellenen Açıklama:
"yüksek seviyeli işlev" anlamına gelen .extend yerleşik değildir, ancak genellikle jQuery veya Prototype gibi bir kitaplık tarafından sağlanır.
changing the native objects can break other developer's assumptions of these objects,
, izlenmesi genellikle saatler süren javascript hatalarının ortaya çıkmasıdır. Bu cevabın başındaki cümle, bu değerli javascript uygulamasını yanlış temsil ediyor gibi görünüyor.
.extend()
diğer nesnelerden nesne oluşturmayı kolaylaştırmak için birçok üçüncü taraf kitaplığı tarafından eklenir. Bazı örnekler için http://api.jquery.com/jQuery.extend/ veya http://www.prototypejs.org/api/object/extend adresine bakın .
.prototype
bir nesnenin "şablonunu" (onu çağırmak istiyorsanız) ifade eder, bu nedenle bir nesnenin prototipine yöntemler ekleyerek (bunu kitaplıklarda String, Date, Math ve hatta Function'a eklemek için çok görürsünüz) bu yöntemler o nesnenin her yeni örneğine eklenir.
extend
Örneğin bir yöntem jQuery veya PrototypeJS , hedef nesnenin kaynaktan kopyaları özellikleri.
Şimdi hakkında prototype
özellik işlev nesnelerinin bir üyesidir, dil çekirdeğinin bir parçasıdır.
Yeni nesne örnekleri oluşturmak için herhangi bir işlev kurucu olarak kullanılabilir . Tüm işlevler buna sahiptirprototype
özelliğe sahiptir.
new
İşleci bir işlev nesnesi üzerinde kullandığınızda, yeni bir nesne oluşturulur ve kurucusundan miras alınır.prototype
.
Örneğin:
function Foo () {
}
Foo.prototype.bar = true;
var foo = new Foo();
foo.bar; // true
foo instanceof Foo; // true
Foo.prototype.isPrototypeOf(foo); // true
Javascript kalıtımı her yerde açık bir tartışma gibi görünüyor. "Javascript dilinin ilginç durumu" olarak adlandırılabilir.
Buradaki fikir, bir temel sınıf olduğu ve ardından kalıtım benzeri bir özellik (tamamen değil ama yine de) elde etmek için temel sınıfı genişletmenizdir.
Bütün fikir, prototipin gerçekte ne anlama geldiğini anlamaktır. John Resig'in kodunu görene kadar alamadım (yakınjQuery.extend
) bunu yapan bir kod parçası yazana kadar anlamadım ve o, baz2 ve prototip kitaplıklarının ilham kaynağı olduğunu iddia etti.
İşte kod.
/* 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;
};
})();
İşi yapan üç bölüm var. İlk olarak, özellikler arasında döngü oluşturur ve bunları örneğe eklersiniz. Bundan sonra, nesneye daha sonra eklenmek üzere bir kurucu oluşturursunuz. Şimdi, ana satırlar:
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
Önce Class.prototype
istediğiniz prototipe yöneltin. Şimdi, tüm nesne değişti, yani düzeni tekrar kendi haline zorlamanız gerekiyor.
Ve kullanım örneği:
var Car = Class.Extend({
setColor: function(clr){
color = clr;
}
});
var volvo = Car.Extend({
getColor: function () {
return color;
}
});
John Resig'in gönderisinin yazdığı Javascript Inheritance'ta bunun hakkında daha fazla bilgi edinin .
extend
Üçüncü taraf kitaplıklarındaki bazı işlevler diğerlerinden daha karmaşıktır. Örneğin Knockout.js , jQuery'nin yaptığı bazı kontrollere sahip olmayan, minimal düzeyde basit bir tane içerir:
function extend(target, source) {
if (source) {
for(var prop in source) {
if(source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
.extends()
başka bir sınıfın çocuğu olan bir sınıf yaratın. Child.prototype.__proto__
, değerini, Parent.prototype
.prototype
özellikleri birinden diğerine devralır..__proto__
Prototip için bir alıcı / ayarlayıcıdır.
.extend
yerleşik değildir, ancak genellikle jQuery veya Prototype gibi bir kitaplık tarafından sağlanır.