Answers:
Javascript的继承是基于原型的,因此您可以扩展对象的原型,例如Date,Math,甚至是您自己的自定义对象。
Date.prototype.lol = function() {
alert('hi');
};
( new Date ).lol() // alert message
在上面的代码段中,我为所有 Date对象(现有对象和所有新对象)定义了一个方法。
extend
通常是一个高级函数,用于复制要从基类扩展的新子类的原型。
因此,您可以执行以下操作:
extend( Fighter, Human )
并且Fighter
构造函数/对象将继承的原型Human
,因此,如果您定义诸如live
and die
on之类的方法,Human
则Fighter
也将继承这些方法。
更新的说明:
“高级功能”的意思是.extend不是内置的,但通常由jQuery或Prototype之类的库提供。
changing the native objects can break other developer's assumptions of these objects,
导致javascript错误,通常可能需要花费数小时才能进行跟踪。此答案的开头一句话似乎歪曲了这种有价值的javascript做法。
.extend()
许多第三方库都添加了,从而可以轻松地从其他对象创建对象。有关某些示例,请参见http://api.jquery.com/jQuery.extend/或http://www.prototypejs.org/api/object/extend。
.prototype
指对象的“模板”(如果要调用它的话),因此通过将方法添加到对象的原型中(在库中可以看到很多,可以添加到String,Date,Math甚至Function中),这些方法被添加到该对象的每个新实例。
的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继承似乎到处都是公开辩论。可以将其称为“ Java语言的奇特案例”。
这个想法是有一个基类,然后您扩展该基类以获得类似继承的功能(不完全,但仍然)。
整个想法是获得原型的真正含义。直到我看到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;
};
})();
工作分为三个部分。首先,您遍历属性并将其添加到实例。之后,创建一个构造函数供以后添加到对象中,现在关键行是:
// 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;
}
});
在John Resig的文章《Javascript继承》中阅读有关此内容的更多信息。
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;
}
.extend
不是内置的,而是通常由jQuery或Prototype之类的库提供。