JavaScript: для чего используются .extend и .prototype?
122
Я относительно новичок в JavaScript и продолжаю видеть .extend и .prototype в сторонних библиотеках, которые я использую. Я думал, что это связано с javascript-библиотекой Prototype, но я начинаю думать, что это не так. Для чего они используются?
В приведенном выше фрагменте я определяю метод для всех объектов Date (уже существующих и всех новых).
extend обычно является функцией высокого уровня, копирующей прототип нового подкласса, который вы хотите расширить от базового класса.
Итак, вы можете сделать что-то вроде:
extend(Fighter,Human)
И Fighterконструктор / объект унаследует прототип Human, поэтому, если вы определите такие методы, как liveи dieon, Humanтогда Fighterони также унаследуют их.
Обновленное разъяснение:
"функция высокого уровня", означающая .extend не является встроенной, но часто предоставляется библиотекой, такой как jQuery или Prototype.
«функция высокого уровня» означает, что .extendона не встроена, но часто предоставляется библиотекой, такой как jQuery или Prototype.
visum
13
Я бы добавил, что расширять прототипы нативных объектов в JS не предлагается
framp
1
@meder - вы должны добавить визуальный комментарий в свой ответ. :)
Маниш Гупта
9
В современном программировании на Javascript глобальные и собственные объекты принято рассматривать как элементы общей ванной комнаты; вы не можете не попасть туда, но вам следует постараться свести к минимуму контакт с поверхностями. Это потому, что это changing the native objects can break other developer's assumptions of these objects,приводит к ошибкам javascript, на отслеживание которых часто может уйти много часов. Кажется, что первое предложение в этом ответе искажает эту ценную практику javascript.
.prototype относится к «шаблону» (если вы хотите его так называть) объекта, поэтому, добавляя методы к прототипу объекта (вы часто видите это в библиотеках для добавления в String, Date, Math или даже Function) эти методы добавляются к каждому новому экземпляру этого объекта.
Наследование 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 classClass.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 =newthis();
initializing =false;// Copy the properties over onto the new prototypefor(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){returnfunction(){var tmp =this._super;// Add a new ._super() method that is the same method// but on the super-classthis._super = _super[name];// The method only need to be bound temporarily, so we// remove it when we're done executingvar ret = fn.apply(this, arguments);this._super = tmp;return ret;};})(name, prop[name]):
prop[name];}// The dummy class constructorfunctionClass(){// All construction is actually done in the init methodif(!initializing &&this.init )this.init.apply(this, arguments);}// Populate our constructed prototype objectClass.prototype = prototype;// Enforce the constructor to be what we expectClass.prototype.constructor=Class;// And make this class extendableClass.extend = arguments.callee;returnClass;};})();
Есть три части, которые делают работу. Сначала вы просматриваете свойства и добавляете их в экземпляр. После этого вы создаете конструктор, который позже будет добавлен к объекту. Теперь ключевые строки:
// Populate our constructed prototype objectClass.prototype = prototype;// Enforce the constructor to be what we expectClass.prototype.constructor=Class;
Сначала вы указываете Class.prototypeна желаемый прототип. Теперь весь объект изменился, а это означает, что вам нужно принудительно вернуть макет к его собственному.
И пример использования:
varCar=Class.Extend({
setColor:function(clr){
color = clr;}});var volvo =Car.Extend({
getColor:function(){return color;}});
Некоторые 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__ является геттером / сеттером для Prototype.
.extend
она не встроена, но часто предоставляется библиотекой, такой как jQuery или Prototype.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
оператор with для объекта функции, будет создан новый объект, который будет унаследован от своего конструктора.prototype
.Например:
источник
Наследование Javascript повсюду похоже на открытые дебаты. Его можно назвать «Любопытным случаем языка Javascript».
Идея состоит в том, что существует базовый класс, а затем вы расширяете базовый класс, чтобы получить функцию, подобную наследованию (не полностью, но все же).
Вся идея в том, чтобы понять, что на самом деле означает прототип. Я не понял этого, пока не увидел, что код Джона Ресига (близкий к тому, что
jQuery.extend
есть) написал фрагмент кода, который это делает, и он утверждает, что библиотеки base2 и прототипов были источником вдохновения.Вот код.
Есть три части, которые делают работу. Сначала вы просматриваете свойства и добавляете их в экземпляр. После этого вы создаете конструктор, который позже будет добавлен к объекту. Теперь ключевые строки:
Сначала вы указываете
Class.prototype
на желаемый прототип. Теперь весь объект изменился, а это означает, что вам нужно принудительно вернуть макет к его собственному.И пример использования:
Узнайте больше об этом здесь, в сообщении Джона Ресига « Наследование Javascript ».
источник
Некоторые
extend
функции в сторонних библиотеках сложнее других. Knockout.js, например, содержит минимально простой файл, в котором нет некоторых проверок, которые выполняет jQuery:источник
.extends()
создать класс, который является потомком другого класса.за кулисами
Child.prototype.__proto__
устанавливает свое значениеParent.prototype
таким образом, чтобы методы наследуются.
.prototype
наследуют черты от одного к другому..__proto__
является геттером / сеттером для Prototype.источник