谈谈 Object.create ,JS的原型继承
2016-04-05 16:07
537 查看
谈到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;
};
所谓继承:我理解的是子类继承了父类。当父类发生了变化,遗传了它基因的子类会有影响。相反它的子类发生了变化,不会影响到父类
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;
};
相关文章推荐
- 【iOS开发技术】对象关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- Hibernate报错:org.hibernate.ObjectNotFoundException: No row with the given identifier exists 解决办法
- Objective-c 内存管理-MRC 引用计数器
- Objective-c 内存管理-MRC retain&release
- Delphi_07_Delphi_Object_Pascal_基本语法_05_函数参数
- android 子线程通过bundle、handler.sendMessage(message)向主线程传输多个类型数据,包括list<Map<String,Object>>
- Json.net/Newtonsoft 新特性JObject/Linq to Json
- 如何遍历newtonsoft.json的JObject里的JSON数据
- makeObjectsPerformSelector
- @synthesize managedObjectModel = _managedObjectModel;
- object-c中的BOOL类型
- Objective-C中的Hello World
- WaitForMultipleObjects使用详解
- 对象关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- Objective-C编码规范
- 阅读 理解 思考 - Learning to Segment Object Candidates
- Excel里如何插入package object
- Object类中的equals();hashcode();toString()方法
- 序列化机制
- java中ObjectOutputStream和ObjectInputStream的使用