JavaScript: что такое.расширить и.прототип используется для?
Я относительно новичок в JavaScript и продолжаю видеть .расширить и. прототип в сторонних библиотеках, которые я использую. Я думал, что это связано с прототипом библиотеки javascript, но я начинаю думать, что это не так. Для чего они используются?
5 ответов
наследование Javascript основано на прототипе, поэтому вы расширяете прототипы объектов, таких как дата, математика и даже собственные пользовательские.
Date.prototype.lol = function() {
alert('hi');
};
( new Date ).lol() // alert message
в приведенном выше фрагменте, я определяю метод все объекты даты ( уже существующие и все новые).
extend
обычно является функцией высокого уровня, которая копирует прототип нового подкласса, который вы хотите расширить из базового класса.
так что вы можете сделать что-то например:
extend( Fighter, Human )
и Fighter
конструктор/объект наследует прототип Human
, поэтому, если вы определяете такие методы, как live
и die
on Human
затем Fighter
также унаследует их.
Обновлены Разъяснения:
"высокого уровня", что означает .extend не является встроенным, но часто предоставляется библиотекой, такой как jQuery или Prototype.
.extend()
добавляется многими сторонними библиотеками, чтобы упростить создание объектов из других объектов. См.http://api.jquery.com/jQuery.extend/ или http://www.prototypejs.org/api/object/extend для некоторых примеров.
.prototype
относится к "шаблону" (если вы хотите его так назвать) объекта, поэтому, добавляя методы к прототипу объекта (вы видите это много в библиотеках для добавления в строку, дату, математику или даже функцию), эти методы добавляются к каждому новому экземпляру этого объекта.
на 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".
идея заключается в том, что существует базовый класс, а затем вы расширяете базовый класс, чтобы получить функцию наследования (не полностью, но все же).
вся идея состоит в том, чтобы получить то, что прототип действительно означает. Я не получил его, пока не увидел код Джона Resig (близко к тому, что 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 от John Resig с должности.
некоторые extend
функции в сторонних библиотеках более сложны, чем другие. нокаут.js например, содержит минимально простой, который не имеет некоторых проверок, которые делает jQuery:
function extend(target, source) {
if (source) {
for(var prop in source) {
if(source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}