JavaScript:什么是.extend和.prototype用于?

我对JavaScript比较陌生,在我使用的第三方库中看到.extend和.prototype。 我认为这是与原型JavaScript库,但我开始认为是不是这种情况。 这些用于什么?

Javascript的inheritance是基于原型的,所以你扩展了对象的原型,比如Date,Math,甚至你自己定制的。

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

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

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

所以你可以做这样的事情:

 extend( Fighter, Human ) 

Fighter构造函数/对象将inheritanceHuman的原型,所以如果你定义了Human diedie等方法,那么Fighter也将inheritance这些。

更新说明:

“高级function”含义.extend不是内置的,而是通常由诸如jQuery或Prototype之类的库提供。

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

.prototype指的是对象的“模板”(如果你想调用它的话),所以通过向对象的原型添加方法(你可以在库中看到很多东西来添加到string,date,math甚至函数中)这些方法被添加到该对象的每个新实例。

例如在jQuery或PrototypeJS中的extend方法,将所有属性从源复制到目标对象。

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

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

当你在一个函数对象上使用new运算符时,将会创build一个新的对象,它将inheritance它的构造函数prototype

例如:

 function Foo () { } Foo.prototype.bar = true; var foo = new Foo(); foo.bar; // true foo instanceof Foo; // true Foo.prototype.isPrototypeOf(foo); // true 

JavaScript的inheritance似乎是一个公开的辩论无处不在。 它可以被称为“JavaScript语言的好奇的情况”。

这个想法是有一个基类,然后扩展基类来获得类似inheritance的function(不完全,但仍然)。

整个想法是获得原型的真正意义。 直到我看到John 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; }; })(); 

有三个部分在做这项工作。 首先,循环访问属性并将其添加到实例中。 之后,您将创build一个构造函数,以便稍后添加到该对象。现在,关键线是:

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

阅读更多关于它在这里的Javascriptinheritance由约翰Resig的职位。

第三方库中的一些extendfunction比其他function更为复杂。 例如Knockout.js包含一个最简单的例子,它没有jQuery所做的一些检查:

 function extend(target, source) { if (source) { for(var prop in source) { if(source.hasOwnProperty(prop)) { target[prop] = source[prop]; } } } return target; }