“类”的设计模式

2018-09-10  本文已影响0人  jy789

类的设计模式:实例化、继承和(相对)多态。

JavaScript通过原型链,在两个对象之间创建一个关联。这样,一个对象就可以通过委托访问另一个对象的属性和函数,从而达到“继承”的实现。

下面来看一个例子:


function Foo(name) {

  this.name = name;

}

Foo.prototype.myName = function () {

  return this.name;

};

function Bar(name, label) {

  Foo.call(this, name);

  this.label = label;

}

Bar.prototype = new Foo(); //实现prototype的关联

Bar.prototype.myLabel = function () {

  return this.label;

};

var a = new Bar("a", "obj a");

a.myName(); // "a"

a.myLabel(); // "obj a"

构造函数和实例原型的关系图(红色的就是原型链)

image

原型prototype

每个函数都有一个prototype属性,函数的prototype属性指向了一个对象,这个对象正是调用该构造函数而创建的实例的原型。例子中Bar.prototype就是实例a的原型。

proto

这是每一个JavaScript对象(除了 null )都具有的一个属性,叫proto,这个属性会指向该对象的原型。


a.__proto__ === Bar.prototype //true

Bar.prototype.__proto__ === Foo.prototype //true

constructor

constructor,每个原型都有一个 constructor 属性指向关联的构造函数。


Foo === Foo.prototype.constructor

为了方便理解,这里我们简单模拟实现new


function objectFactory() {

  var obj = new Object(),Constructor = [].shift.call(arguments);

  obj.__proto__ = Constructor.prototype;

  var ret = Constructor.apply(obj, arguments);

  return typeof ret === 'object' ? ret : obj;

};

下面介绍,另外两种写法:

Object.create(行为委托设计模式)


var Foo = {

  init: function(name){

    this.name = name;

  },

  myName: function(){

    return this.name;

  }

};

var Bar = Object.create(Foo);

Bar.setup = function(name, label){

  // 委托调用

  this.init(name);

  this.label = label;

};

Bar.myLabel = function(){

  return this.label;

};

var a = Object.create( Bar );

a.setup("a", "obj a");

a.myName(); // "a"

a.myLabel(); // "obj a"

简单模拟实现Object.create


Object.create = function (o) {

  var F = function () {};

  F.prototype = o;

  return new F();

};

class(class 语法可以简洁地定义类方法)


class Foo {

  constructor(name) {

    this.name = name;

  }

  myName() {

    return this.name;

  }

}

class Bar extends Foo {

  constructor(props, label) {

    super(props);

    this.label = label;

  }

  myLabel() {

    return this.label;

  }

}

var a = new Bar("a", "obj a");

a.myName(); // "a"

a.myLabel(); // "obj a"

上一篇下一篇

猜你喜欢

热点阅读