Jawaban:
Pewarisan Javascript berbasis prototipe, jadi Anda memperluas prototipe objek seperti Tanggal, Matematika, dan bahkan objek kustom Anda sendiri.
Date.prototype.lol = function() {
alert('hi');
};
( new Date ).lol() // alert message
Dalam potongan di atas, saya mendefinisikan metode untuk semua objek Tanggal (yang sudah ada dan yang baru).
extend
biasanya adalah fungsi tingkat tinggi yang menyalin prototipe subkelas baru yang ingin Anda kembangkan dari kelas dasar.
Jadi Anda bisa melakukan sesuatu seperti:
extend( Fighter, Human )
Dan Fighter
konstruktor / objek akan mewarisi prototipe Human
, jadi jika Anda mendefinisikan metode seperti live
dan die
di Human
kemudian Fighter
juga akan mewarisi mereka.
Klarifikasi yang Diperbarui:
"fungsi tingkat tinggi" yang berarti .extend tidak built-in tetapi sering disediakan oleh perpustakaan seperti jQuery atau Prototype.
changing the native objects can break other developer's assumptions of these objects,
menyebabkan bug javascript yang seringkali membutuhkan waktu berjam-jam untuk melacaknya. Kalimat utama pada jawaban ini tampaknya salah menggambarkan praktik javascript yang berharga ini.
.extend()
ditambahkan oleh banyak pustaka pihak ketiga untuk memudahkan pembuatan objek dari objek lain. Lihat http://api.jquery.com/jQuery.extend/ atau http://www.prototypejs.org/api/object/extend untuk beberapa contoh.
.prototype
mengacu pada "template" (jika Anda ingin menyebutnya demikian) dari suatu objek, jadi dengan menambahkan metode ke prototipe objek (Anda sering melihat ini di perpustakaan untuk ditambahkan ke String, Tanggal, Matematika, atau bahkan Fungsi) metode tersebut ditambahkan ke setiap kemunculan baru dari objek itu.
The extend
Metode misalnya dalam jQuery atau PrototypeJS , salinan semua properti dari sumber ke objek tujuan.
Sekarang tentang prototype
properti, itu adalah anggota objek fungsi, itu adalah bagian dari inti bahasa.
Fungsi apa pun dapat digunakan sebagai konstruktor , untuk membuat instance objek baru. Semua fungsi memiliki prototype
properti ini .
Saat Anda menggunakan new
operator dengan pada objek fungsi, objek baru akan dibuat, dan itu akan mewarisi dari konstruktornya prototype
.
Sebagai contoh:
function Foo () {
}
Foo.prototype.bar = true;
var foo = new Foo();
foo.bar; // true
foo instanceof Foo; // true
Foo.prototype.isPrototypeOf(foo); // true
Warisan Javascript sepertinya menjadi perdebatan terbuka di mana-mana. Ini bisa disebut "Kasus aneh bahasa Javascript".
Idenya adalah bahwa ada kelas dasar dan kemudian Anda memperluas kelas dasar untuk mendapatkan fitur seperti pewarisan (tidak sepenuhnya, tapi tetap saja).
Keseluruhan idenya adalah untuk mendapatkan arti sebenarnya dari prototipe. Saya tidak mendapatkannya sampai saya melihat kode John Resig (mendekati apa yang jQuery.extend
dilakukannya) menulis potongan kode yang melakukannya dan dia mengklaim bahwa pustaka base2 dan prototipe adalah sumber inspirasi.
Ini kodenya.
/* 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;
};
})();
Ada tiga bagian yang melakukan pekerjaan itu. Pertama, Anda mengulang properti dan menambahkannya ke instance. Setelah itu, Anda membuat konstruktor untuk kemudian ditambahkan ke objek. Sekarang, baris kuncinya adalah:
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
Anda pertama kali mengarahkan Class.prototype
ke prototipe yang diinginkan. Sekarang, seluruh objek telah berubah artinya Anda perlu memaksa tata letak kembali ke tempatnya sendiri.
Dan contoh penggunaan:
var Car = Class.Extend({
setColor: function(clr){
color = clr;
}
});
var volvo = Car.Extend({
getColor: function () {
return color;
}
});
Baca lebih lanjut tentang itu di sini di Javascript Inheritance oleh posting John Resig .
Beberapa extend
fungsi di pustaka pihak ketiga lebih kompleks daripada yang lain.Knockout.js misalnya berisi yang minimal sederhana yang tidak memiliki beberapa pemeriksaan seperti yang dilakukan jQuery:
function extend(target, source) {
if (source) {
for(var prop in source) {
if(source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
.extends()
membuat kelas yang merupakan anak dari kelas lain. Child.prototype.__proto__
menetapkan nilainya Parent.prototype
.prototype
mewarisi fitur dari satu sama lain..__proto__
adalah pengambil / penyetel untuk Prototipe.
.extend
tidak built-in tetapi sering disediakan oleh perpustakaan seperti jQuery atau Prototipe.