JavaScript: What are .extend and .prototype used for?
Asked Answered
R

7

128

I am relatively new to JavaScript and keep seeing .extend and .prototype in third party libraries I am using. I thought it had to do with the Prototype javascript library, but I am beginning to think that is not the case. What are these used for?

Rouvin answered 23/9, 2010 at 18:23 Comment(1)
if you want to learn more about this prototype stuff i recommend on khan academy khanacademy.org/computing/computer-programming/programming/…Feldspar
E
141

Javascript's inheritance is prototype based, so you extend the prototypes of objects such as Date, Math, and even your own custom ones.

Date.prototype.lol = function() {
 alert('hi');
};

( new Date ).lol() // alert message

In the snippet above, I define a method for all Date objects ( already existing ones and all new ones ).

extend is usually a high level function that copies the prototype of a new subclass that you want to extend from the base class.

So you can do something like:

extend( Fighter, Human )

And the Fighter constructor/object will inherit the prototype of Human, so if you define methods such as live and die on Human then Fighter will also inherit those.

Updated Clarification:

"high level function" meaning .extend isn't built-in but often provided by a library such as jQuery or Prototype.

Excited answered 23/9, 2010 at 18:27 Comment(4)
"high level function" meaning .extend isn't built-in but often provided by a library such as jQuery or Prototype.Leprose
I would add it's not suggested to extend the prototypes of native objects in JSAglimmer
@meder - you should add visum comment in your answer. :)Hypnotherapy
In modern Javascript programming, it's customary to treat globals and native objects like elements of a public bathroom; you can't avoid going in there, but you should try to minimize contact with surfaces. This is because changing the native objects can break other developer's assumptions of these objects, leading to javascript bugs which can often cost many hours to tracking down. The leading sentence on this answer seems to misrepresent this valuable javascript practice.Varner
K
25

.extend() is added by many third-party libraries to make it easy to create objects from other objects. See http://api.jquery.com/jQuery.extend/ or http://www.prototypejs.org/api/object/extend for some examples.

.prototype refers to the "template" (if you want to call it that) of an object, so by adding methods to an object's prototype (you see this a lot in libraries to add to String, Date, Math, or even Function) those methods are added to every new instance of that object.

Kalpa answered 23/9, 2010 at 18:29 Comment(0)
B
19

The extend method for example in jQuery or PrototypeJS, copies all properties from the source to the destination object.

Now about the prototype property, it is a member of function objects, it is part of the language core.

Any function can be used as a constructor, to create new object instances. All functions have this prototype property.

When you use the new operator with on a function object, a new object will be created, and it will inherit from its constructor prototype.

For example:

function Foo () {
}
Foo.prototype.bar = true;

var foo = new Foo();

foo.bar; // true
foo instanceof Foo; // true
Foo.prototype.isPrototypeOf(foo); // true
Behlke answered 23/9, 2010 at 18:33 Comment(0)
P
18

Javascript inheritance seems to be like an open debate everywhere. It can be called "The curious case of Javascript language".

The idea is that there is a base class and then you extend the base class to get an inheritance-like feature (not completely, but still).

The whole idea is to get what prototype really means. I did not get it until I saw John Resig's code (close to what jQuery.extend does) wrote a code chunk that does it and he claims that base2 and prototype libraries were the source of inspiration.

Here is the code.

    /* 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;
  };
})();

There are three parts which are doing the job. First, you loop through the properties and add them to the instance. After that, you create a constructor for later to be added to the object.Now, the key lines are:

// Populate our constructed prototype object
Class.prototype = prototype;

// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;

You first point the Class.prototype to the desired prototype. Now, the whole object has changed meaning that you need to force the layout back to its own one.

And the usage example:

var Car = Class.Extend({
  setColor: function(clr){
    color = clr;
  }
});

var volvo = Car.Extend({
   getColor: function () {
      return color;
   }
});

Read more about it here at Javascript Inheritance by John Resig 's post.

Physicality answered 12/12, 2013 at 10:19 Comment(0)
S
2

Some extend functions in third party libraries are more complex than others. Knockout.js for instance contains a minimally simple one that doesn't have some of the checks that jQuery's does:

function extend(target, source) {
    if (source) {
        for(var prop in source) {
            if(source.hasOwnProperty(prop)) {
                target[prop] = source[prop];
            }
        }
    }
    return target;
}
Ship answered 14/3, 2017 at 7:0 Comment(0)
R
2
  • .extends() create a class which is a child of another class.
    behind the scenes Child.prototype.__proto__ sets its value to Parent.prototype
    so methods are inherited.
  • .prototype inherit features from one to another.
  • .__proto__ is a getter/setter for Prototype.
Refrigerate answered 23/9, 2019 at 8:19 Comment(1)
Should this not be .extend() and not .extends() ?Madelainemadeleine
C
0

This seems to be the clearest and simplest example to me, this just appends property or replaces existing.

function replaceProperties(copyTo, copyFrom)  {
  for (var property in copyFrom) 
    copyTo[property] =  copyFrom[property]
  return copyTo
}
Catchfly answered 30/11, 2020 at 8:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.