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;
}