Відповіді:
Спадщина 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 або прототип.
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
посилається на "шаблон" (якщо ви хочете це назвати) об'єкта, тому додаючи методи до прототипу об'єкта (ви багато бачите в бібліотеках, щоб додати до 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
робить), написав фрагмент коду, який це робить, і він стверджує, що бібліотеки 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;
};
})();
Є три частини, які роблять цю роботу. Спочатку ви перебираєте властивості та додаєте їх до екземпляра. Після цього ви створюєте конструктор для подальшого додавання до об'єкта. Тепер ключовими рядками є:
// 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;
}
});
Детальніше про це читайте тут, на адресу спадщини 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;
}
.extends()
створити клас, який є дитиною іншого класу. Child.prototype.__proto__
встановлює своє значення, Parent.prototype
.prototype
успадковувати риси від однієї до іншої..__proto__
- це геттер / сетер для прототипу.
.extend
не є вбудованим, але часто надається бібліотекою, такою як jQuery або Prototype.