JavaScript:.extend 和 .prototype 有什么用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3781373/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:08:20  来源:igfitidea点击:

JavaScript: What are .extend and .prototype used for?

javascriptprototypeobject-model

提问by Andrew

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?

我对 JavaScript 比较陌生,并且一直在我使用的第三方库中看到 .extend 和 .prototype 。我认为这与 Prototype javascript 库有关,但我开始认为情况并非如此。这些是做什么用的?

回答by meder omuraliev

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

Javascript 的继承是基于原型的,因此您可以扩展对象的原型,例如 Date、Math,甚至您自己的自定义对象。

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

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

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

在上面的代码片段中,我为所有Date 对象(已经存在的和所有新的)定义了一个方法。

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

extend通常是一个高级函数,它复制要从基类扩展的新子类的原型。

So you can do something like:

因此,您可以执行以下操作:

extend( Fighter, Human )

And the Fighterconstructor/object will inherit the prototype of Human, so if you define methods such as liveand dieon Humanthen Fighterwill also inherit those.

并且Fighter构造函数/对象将继承 的原型Human,因此如果您定义了诸如live和 之类的方法dieHuman那么Fighter也将继承这些。

Updated Clarification:

更新说明:

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

“高级函数”意味着 .extend 不是内置的,但通常由 jQuery 或 Prototype 等库提供。

回答by pnomolos

.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/extendfor some examples.

.extend()由许多第三方库添加,以便于从其他对象创建对象。有关一些示例,请参阅http://api.jquery.com/jQuery.extend/http://www.prototypejs.org/api/object/extend

.prototyperefers 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.

.prototype指的是对象的“模板”(如果你想这样称呼它),所以通过向对象的原型添加方法(你在库中看到很多添加到字符串、日期、数学甚至函数的方法)这些方法被添加到该对象的每个新实例中。

回答by CMS

The extendmethod for example in jQueryor PrototypeJS, copies all properties from the source to the destination object.

extend,例如在方法的jQueryPrototypeJS,复制所有从源到目的对象的属性。

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

现在关于prototype属性,它是函数对象的成员,它是语言核心的一部分。

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

任何函数都可以用作构造函数,以创建新的对象实例。所有函数都有这个prototype属性。

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

当您new在函数对象上使用运算符 with 时,将创建一个新对象,它将从其构造函数继承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

回答by ambodi

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

Javascript 继承似乎无处不在。它可以称为“Javascript 语言的奇特案例”。

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.extenddoes) wrote a code chunk that does it and he claims that base2 and prototype libraries were the source of inspiration.

整个想法是了解原型的真正含义。直到我看到 John Resig 的代码(接近于jQuery.extend它所做的)编写了一个代码块,并且他声称 base2 和原型库是灵感的来源,我才明白。

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.prototypeto the desired prototype. Now, the whole object has changed meaning that you need to force the layout back to its own one.

您首先将 指向Class.prototype所需的原型。现在,整个对象发生了变化,这意味着您需要将布局强制恢复为自己的布局。

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.

John Resig的文章Javascript Inheritance 中阅读有关它的更多信息。

回答by Simon_Weaver

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

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

回答by humaid

  • .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.
  • .prototypeinherit features from one to another.
  • .__proto__is a getter/setter for Prototype.
  • .extends()创建一个类,它是另一个类的子类。
    在幕后 Child.prototype.__proto__将其值设置为Parent.prototype
    这样可以继承方法。
  • .prototype从一个继承特征到另一个。
  • .__proto__是 Prototype 的 getter/setter。