3.Contructor(构造器)模式—精读《JavaScript 设计模式》Addy Osmani著

同系列友情连接:


1.设计模式之初体验—精读《JavaScript 设计模式》Addy Osmani著
2.设计模式的分类—精读《JavaScript 设计模式》Addy Osmani著

Construct(构造器)模式


在经典的面向对象编程语言中,Construtor是一种在内存已分配给该对象的状况下,用于初始化新建立对象的特殊方法。javascript

在 JavaScript 中,几乎全部东西都是都是对象,可能你会常常找不到对象,😝,你认可不?😁java

来看一下什么是 Object构造器 :编程

用于建立特定类型的对象——准备好对象以备使用,同时接受构造器可使用的参数,以在第一次建立对象时,设置成员属性和方法值。设计模式

下图为:Constructor(构造器)模式 编程语言

Object构造器

对象的建立

在 JavaScript 中,建立对象时有发生,常见的建立方式有两种:模块化

  1. 直接空对象赋值;
  2. 使用 new关键字
// 1. 直接空对象赋值
var newObject = {};

// 2. 使用 new 关键字建立,newObject构造器的简洁记法
var newObject = new Object();
复制代码

在 Object构造器为特定的值建立对象封装,或者没有传递值时,它将建立 一个空对象并返回这个空对象;函数

对象的赋值

四种方法能够将键值赋值给一个对象:post

  1. ECMAScript 3 兼容方式;
    1. “点”语法;
    2. 中括号语法
  2. 只适用于ECMAScript 5 方式;
    1. Object.defineProperty;
    2. Object.defineProperties
// 1.点语法
// 设置属性
newObject.someKey = "Hello World!";
// 获取属性值
var key = newObject.someKey;


// 2.中括号语法
// 设置属性
newObject["somekey"] = "Hello world!";
// 获取属性值
var key = newObject["somekey"];


// 3.Object.defineProperty
// 设置属性
Object.defineProperty(newObject,"somekey",{
    value:"Hello World!",// 该属性对应的值,默认为undefined
    writable:true,// 可否修改属性的值,若是直接使用字面量定义对象,默认值为true
    enumerable:true,// 表示该属性是否可枚举,便是否经过for-in循环或Object.keys()返回属性,若是直接使用字面量定义对象,默认值为true
    configurable:true// 表示可否经过delete删除此属性,可否修改属性的特性,或可否修改把属性修改成访问器属性,若是直接使用字面量定义对象,默认值为true
});
// 也能够简化一下这种方式
var defineProp = function(obj,key,value){
    config.value=value;
    Object.defineProperty(obj,key,config);
}
// 使用上述方式,先建立一个空的 person对象
var person = Object.create(null);
// 而后设置各个属性
defineProp(person,"car","Delorean");
defineProp(person,"dateOfBrith","1989");
defineProp(person,"hasBeard",false);
// 获取属性值同1,2
var key_car = person["car"];
var key_dateOfBrith = person["dateOfBrith"];
var key_hasBeard = person["hasBeard"];


// 4.Object.defineProperties
// 设置属性
Object.defineProperties(newObject,{
    "someKey":{
        value:"Hello World!",
        writable:true
    },
    "anotherKey":{
        value:"Foo Bar",
        writable:false
    }
});
// 获取属性值同1,2
var key_someKey = person["someKey"];
var key_anotherKey = person["anotherKey"];

复制代码

上面定义的这些方法甚至能够用于继承以下所示:ui

// 用法
// 建立赛车司机 driver 对象,继承于 person 对象
var driver = Object.create(person);
// 为 driver 设置一些属性
defineProp(deriver,"topSpeed","100mph");
// 获取继承属性
console.log(driver.dateOfBrith);
// 获取咱们设置的100mph属性
console.log(driver.topSpeed);

复制代码

基本Constructor(构造器)

你们都知道 JavaScript 不支持类的概念,可是它却支持与对象一块儿使用的 特殊的 Constructor 函数。经过在构造器前面加 new关键字,告诉 JavaScript 像使用构造器同样实例化一个新的对象,而且对象成员由该函数定义。this

在构造器内,关键字 this引用新建立的对象。回顾对象建立,基本的构造器看起来多是这样的:

function Car(model,year,miles){
    this.model = model;
    this.year = year;
    this.miles = miles;
    this.toString= function(){
        return this.model+ " has done " + this.miles + " miles";
    }
}
// 用法
var civic = new Car("Honda Civic",2009,20000);
var mondeo= new Car("Ford Mondeo",2010,5000);

console.log(civic.toString());
console.log(mondeo.toString());
复制代码

上面是一个简单的构造器模式版本,可是也是存在问题的:由于她很难继承,另外一个 问题就是 toString()这样的函数是为每一个使用 Car 构造器建立的新对象而从新定义的。 这不是最理想的,由于这种函数应该在全部的 Car 实例之间共享。

其实这个问题很好解决,由于有不少ES3和 ES5兼容替代方法可以用于建立对象。

带原型的Constructor(构造器)

JavaScript中有一个名为 prototype 的属性。调用 JavaScript 构造器建立一个对象后,新的对象就具备构造器原型的全部属性。经过这种方式,能够建立多个 Car 对象,并访问相同的原型。因此咱们能够扩展原始示例,以下所示:

function Car(model,year,miles){
    this.model = model;
    this.year = year;
    this.miles = miles;
}
// 前方警告:小伙伴是否还记得反模式一条:避免从新定义 prototype对象
// 因此下面咱们是使用 Object.prototype.newMethod而不是Object.prototype来定义对象内部的方法
Car.prototype.toString=function(){
    return this.model+ " has done " + this.miles + " miles";
}
// 用法
var civic = new Car("Honda Civic",2009,20000);
var mondeo= new Car("Ford Mondeo",2010,5000);

console.log(civic.toString());
console.log(mondeo.toString());

// 这样 toString()的单一示实例就能够在全部的 Car 对象之间共享了
复制代码

小结

今天的构造器模式,是否是很nice?

可是,你掌握了多少?

你能够动动小手指示例代码都敲一遍,相信你能够更进一步了解,掌握 Constructor(构造器)模式。

下一篇将对Module(模块)模式作详细的介绍。这一模式更精彩,由于很快你就会知道为何别人都那么写了,以及模块化的相关概念等等等

( ^_^ )/~~拜拜

相关文章
相关标签/搜索