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
die
和die
等方法,那么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的职位。
第三方库中的一些extend
function比其他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; }