Відповіді:
Спадщина 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.