您的位置:首页 > 移动开发 > Objective-C

谈谈 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;

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: