谈到Object.create ,那就说说大家常用的原型继承这一块。
所谓继承:我理解的是子类继承了父类。当父类发生了变化,遗传了它基因的子类会有影响。相反它的子类发生了变化,不会影响到父类
ecmascript 5.1 开始 Object 对象添加了create 方法 。 官方描述是:创建一个具有指定原型且可选择性地包含指定属性的对象。
Object.create 其实只是创建了一个函数,再把属性赋给函数原型,再通过new 创建一个新的function 对象.这样它的指针,指向的是函数。而不是且继承的属性。当对象发生变化不会影响继承的属性
Object.create 兼容性写法是:
if (typeof Object.create !== 'function') {
Object.create = function(o) {
function F() { }
F.prototype = o;
return new F();
};
}
不正确的写法:
var parent=function(){} parent.prototype.age=18; var child=function(){} child.prototype=parent.prototype;(这样的话,当child 变化了,会直接影响parent的原型,并且会导致所有继承parent 类的子类)
不正确的写法(误区),那就是原型扩展(这样可以把某个对象的属性或方法,扩展到目标对象上。但是并非真正的继承)
通过一些比如:jquery、zepto 或underscore 的 extend 方法,复制父类属性 对prototype 进行延伸扩展.
一般继承一个父类的写法:
var parent=function(){} parent.prototype.age=18; var child=function(){} child.prototype=Object.crate(parent.prototype);
这样的写法有什么好处呢?它可以创建一个干净 的原型继承模式。
假始我们改变child.prototype的属性或方法。它也不会直接影响它的父类.相反它的父类变化了,它会有影响。
child.prototype.age=80 .
当child 继承了parent ,但它还想扩展其它属性或方法。并且有些属性覆盖它原有继承的属性。但有时候又想使用它父类的属性或方法
这里有三种方法,调用之后。会返回: {age: 18}
child.prototype.__proto__ ecm6 出现的
child.prototype.constructor.prototype
Object.getPrototypeOf(a.prototype) ecm 6 出现的,推荐 使用
最后推荐 几个比较常用的extend 方法,kendo.js 和backbone.js 的继承扩展方法
使用方法:当我需要继承Class 。var childClass=Class.extend({desc:"我的class 的子类"});
var childClass2=childClass.extend({desc:"我是childClass的子类,Class 是我爷爷"})
childClass2 会继承childClass 和Class 的属性和方法
kendo.js 是这样写的,它做了深度复制。
function Class() {}
Class.extend = function(proto) {
var base = function() {},
member,
that = this,
subclass = proto && proto.init ? proto.init : function () {
that.apply(this, arguments);
},
fn;
base.prototype = that.prototype;
fn = subclass.fn = subclass.prototype = new base();
for (member in proto) {
if (typeof proto[member] === OBJECT && !(proto[member] instanceof Array) && proto[member] !== null) {
// Merge object members
fn[member] = extend(true, {}, base.prototype[member], proto[member]);
} else {
fn[member] = proto[member];
}
}
fn.constructor = subclass;
subclass.extend = that.extend;
return subclass;
};
backbone.js
var extend = function(protoProps, staticProps) {
var parent = this;
var child;
// The constructor function for the new subclass is either defined by you
// (the "constructor" property in your `extend` definition), or defaulted
// by us to simply call the parent's constructor.
if (protoProps && _.has(protoProps, 'constructor')) {
child = protoProps.constructor;
} else {
child = function(){ return parent.apply(this, arguments); };
}
// Add static properties to the constructor function, if supplied.
_.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function.
var Surrogate = function(){ this.constructor = child; };
Surrogate.prototype = parent.prototype;
child.prototype = new Surrogate;
// Add prototype properties (instance properties) to the subclass,
// if supplied.
if (protoProps) _.extend(child.prototype, protoProps);
// Set a convenience property in case the parent's prototype is needed
// later.
child.__super__ = parent.prototype;
return child;
};