深入理解JavaScript系列(42):设计模式之原型模式详解


Posted in Javascript onMarch 04, 2015

介绍

原型模式(prototype)是指用原型实例指向创建对象的种类,并且通过拷贝这些原型创建新的对象。

正文

对于原型模式,我们可以利用JavaScript特有的原型继承特性去创建对象的方式,也就是创建的一个对象作为另外一个对象的prototype属性值。原型对象本身就是有效地利用了每个构造器创建的对象,例如,如果一个构造函数的原型包含了一个name属性(见后面的例子),那通过这个构造函数创建的对象都会有这个属性。

在现有的文献里查看原型模式的定义,没有针对JavaScript的,你可能发现很多讲解的都是关于类的,但是现实情况是基于原型继承的JavaScript完全避免了类(class)的概念。我们只是简单从现有的对象进行拷贝来创建对象。

真正的原型继承是作为最新版的ECMAScript5标准提出的,使用Object.create方法来创建这样的对象,该方法创建指定的对象,其对象的prototype有指定的对象(也就是该方法传进的第一个参数对象),也可以包含其他可选的指定属性。例如Object.create(prototype, optionalDescriptorObjects),下面的例子里也可以看到这个用法:

// 因为不是构造函数,所以不用大写

var someCar = {

    drive: function () { },

    name: '马自达 3'

};
// 使用Object.create创建一个新车x

var anotherCar = Object.create(someCar);

anotherCar.name = '丰田佳美';

Object.create运行你直接从其它对象继承过来,使用该方法的第二个参数,你可以初始化额外的其它属性。例如:
var vehicle = {

    getModel: function () {

        console.log('车辆的模具是:' + this.model);

    }

};
var car = Object.create(vehicle, {

    'id': {

        value: MY_GLOBAL.nextId(),

        enumerable: true // 默认writable:false, configurable:false

 },

    'model': {

        value: '福特',

        enumerable: true

    }

});

这里,可以在Object.create的第二个参数里使用对象字面量传入要初始化的额外属性,其语法与Object.defineProperties或Object.defineProperty方法类型。它允许您设定属性的特性,例如enumerable, writable 或 configurable。

如果你希望自己去实现原型模式,而不直接使用Object.create 。你可以使用像下面这样的代码为上面的例子来实现:

var vehiclePrototype = {

    init: function (carModel) {

        this.model = carModel;

    },

    getModel: function () {

        console.log('车辆模具是:' + this.model);

    }

};


function vehicle(model) {

    function F() { };

    F.prototype = vehiclePrototype;
    var f = new F();
    f.init(model);

    return f;

}
var car = vehicle('福特Escort');

car.getModel();

总结

原型模式在JavaScript里的使用简直是无处不在,其它很多模式有很多也是基于prototype的,就不多说了,这里大家要注意的依然是浅拷贝和深拷贝的问题,免得出现引用问题。

Javascript 相关文章推荐
javascript 自定义事件初探
Aug 21 Javascript
C#中使用迭代器处理等待任务
Jul 13 Javascript
JQuery获取鼠标进入和离开容器的方向
Dec 29 Javascript
js简易版购物车功能
Jun 17 Javascript
vue.js组件之间传递数据的方法
Jul 10 Javascript
vue2.x 父组件监听子组件事件并传回信息的方法
Jul 17 Javascript
Node.js调用fs.renameSync报错(Error: EXDEV, cross-device link not permitted)
Dec 27 Javascript
JavaScript多种页面刷新方法小结
Apr 04 Javascript
jQuery - AJAX load() 实例用法详解
Aug 27 jQuery
JS实现点星星消除小游戏
Mar 24 Javascript
JavaScript中如何调用Java方法
Sep 16 Javascript
使用AutoJs实现微信抢红包的代码
Dec 31 Javascript
javascript 动态创建表格的2种方法总结
Mar 04 #Javascript
深入理解JavaScript系列(41):设计模式之模板方法详解
Mar 04 #Javascript
深入理解JavaScript系列(40):设计模式之组合模式详解
Mar 04 #Javascript
百度地图自定义控件分享
Mar 04 #Javascript
jQuery实现仿淘宝带有指示条的图片转动切换效果完整实例
Mar 04 #Javascript
深入理解JavaScript系列(39):设计模式之适配器模式详解
Mar 04 #Javascript
深入理解JavaScript系列(38):设计模式之职责链模式详解
Mar 04 #Javascript
You might like
修改了一个很不错的php验证码(支持中文)
2007/02/14 PHP
php中将数组存到文件里的实现代码
2012/01/19 PHP
php封装的表单验证类完整实例
2016/10/19 PHP
PHP按符号截取字符串的指定部分的实现方法
2018/09/10 PHP
PHP重载基础知识回顾
2020/09/10 PHP
基于node.js的快速开发透明代理
2010/12/25 Javascript
使用jquery读取html5 localstorage的值的方法
2013/01/04 Javascript
ajax请求get与post的区别总结
2013/11/04 Javascript
简单的JS时钟实例讲解
2016/01/13 Javascript
vue项目总结之文件夹结构配置详解
2017/12/13 Javascript
JavaScript获取移动设备型号的实现代码(JS获取手机型号和系统)
2018/03/10 Javascript
jQuery实现的上传图片本地预览效果简单示例
2018/03/29 jQuery
JS实现调用本地摄像头功能示例
2018/05/18 Javascript
webstorm中配置Eslint的两种方式及差异比较详解
2018/10/19 Javascript
原生js+canvas实现贪吃蛇效果
2020/08/02 Javascript
python下解压缩zip文件并删除文件的实例
2018/04/24 Python
Python3.6.0+opencv3.3.0人脸检测示例
2018/05/25 Python
Django中日期处理注意事项与自定义时间格式转换详解
2018/08/06 Python
Python Pandas实现数据分组求平均值并填充nan的示例
2019/07/04 Python
在Pytorch中计算自己模型的FLOPs方式
2019/12/30 Python
tensorflow获取预训练模型某层参数并赋值到当前网络指定层方式
2020/01/24 Python
PyCharm 专业版安装图文教程
2020/02/20 Python
Python 私有属性和私有方法应用场景分析
2020/06/19 Python
伦敦一家领先的精品零售商:IRIS Fashion
2019/05/24 全球购物
Talbots官网:美国成熟女装品牌
2019/11/15 全球购物
在职人员函授期间自我评价分享
2013/11/08 职场文书
后勤部长岗位职责
2013/12/14 职场文书
法律进机关实施方案
2014/03/12 职场文书
负责人任命书范本
2014/06/04 职场文书
医生个人年终总结
2015/02/28 职场文书
计生个人工作总结
2015/02/28 职场文书
医生辞职信范文
2015/03/02 职场文书
教师节班会开场白
2015/06/01 职场文书
学生病假条范文
2015/08/17 职场文书
导游词之塘栖古镇
2019/12/04 职场文书
MySQL Router实现MySQL的读写分离的方法
2021/05/27 MySQL