在大多数面向对象语言中,对象总是由类中实例化而来,类和对象的关系就像模具跟模件一样。Javascript中没有类的概念,就算ES6中引入的class也不过是一种语法糖,本质上还是利用原型实现。在原型编程语言中,类并不是必需的,对象不一定需要由类实例化而来,而是通过克隆另外一个对象来得到。

  原型模式是用来创建对象的一种模式。在以类为中心的语言中,要创建一个对象首先要指定这个对象的类型,然后实例化一个对象。使用原型模式创建对象时不必关心对象的具体类型,而是找到一个对象,然后通过克隆来创建一个一模一样的对象。所以在前者中如果要根据一个对象创建多个相同的对象,我们需要先保存这个对象的所有属性信息,然后将属性信息设置到新创建的对象上,而在原型模式中我们只需要使用克隆就能完成同样的功能。

  在某些玄幻小说中经常会出现某些修真大能,以分身的形式游走世间。这个过程很适合原型模式的应用:

function Master(){
this.blood = 100;
this.level = 6;
} var noumenon = new Master();
noumenon.level = 9; var ektype = Object.create(noumenon); console.log(ektype);

  ES5提供了原生的克隆方法:Object.create,不支持这个方法的浏览器可以使用如下代码:

function clone(obj){
function F(){};
F.prototype = obj;
return new F();
} var ektype = clone(noumenon);

  通过以上代码,我们看到了如何通过原型模式来克隆出一个一模一样的的对象。原型模式的真正意义并非创建一个一模一样的对象,而是提供一种创建对象的方式,Javascript的面向对象机制是基于原型模式的,他的对象系统就是使用原型模式,通过克隆来创建的,克隆是创建一个对象的过程和手段。以继承为例:

function Person(name){
this.name = name;
} function Developer(lang){
this.language = lang;
} var p = new Person('coder'); Developer.prototype = p; var dev = new Developer('Javascript');

  基于原型的继承体系,子类的每次实例化都是对其构造函数的prototype属性的克隆。所以每次创建Developer对象,其实都是在对p对象的克隆。

  在Java等以类为中心的面向对象语言中,经常使用new实例化一个对象。但是Javascript是基于原型的面向对象语言,在这里new运算符创建对象的方式与Java中的new运算符并不相同,Javascript中的new运算符也是通过克隆来实例化对象的,克隆的是构造器函数的原型对象,new运算符的作用等同于如下代码:

function Person(name){
this.name = name;
} function Developer(lang){
this.language = lang;
} var p = new Person('coder'); Developer.prototype = p; function _new(_Constructor) {
var that = Object.create(_Constructor.prototype);
var args = Array.prototype.slice.call(arguments, 1);
var other = _Constructor.apply(that, args); return (typeof other === 'object' && other) ? other : that;
}
_new(Developer, 'JavaScript')

  从这我们也可以看出,Javascript的原型实际上存在着诸多矛盾,它的某些复杂语法看起来就像那些基于类的语言,这掩盖了它的原型机制。所以jQuery中尽量避免使用new运算符来创建对象。

  根据前面所说Javascript中新创建的对象都是基于原有对象的克隆,所以在Javascript中存在一个最原始的对象:Object.prototype,所有对象都是由它克隆而来。

  这里所说的克隆是在Javascript原型模式这一大环境下的一种语义表达,在计算机的物理世界中并不存在真正的克隆。所以这里对于克隆应当理解为产生一个拥有__proto__属性指向原对象的对象的过程,原对象成为被克隆的对象,也就是构造函数的prototype对象。

  拥有以上共识后,我们可以得到在Javascript中原型编程的基本规则:

  1. Javascript中绝大多数数据都是对象
  2. 要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它
  3. 对象会记住它的原型
  4. 如果对象无法响应某个请求,他会把这个请求委托给它自己的原型

参考书籍:

《Javascript语言精粹》

《Javascript设计模式与开发实践》

Javascript原型模式总结梳理的更多相关文章

  1. 面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统

    面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统 原型模式和基于原型继承的JavaScript对象系统 在 Brendan Eich 为 JavaScrip ...

  2. JavaScript原型模式

    一.提到原型模式,和构造函数关系密切,先讲一下它 javascript没有类,通过函数来模拟实现类,用new来创建对象,函数内部的this指针来指向调用它的对象. 事例中创建对象myGril,这个对象 ...

  3. Javascript:原型模式类继承

    原型模式 每个函数(准确说不是类.对象)都有一个prototype属性,这个属性是一个指针,指向一个对象. 使用原型对象的好处是可以让所有对象实例共享它包含的属性和方法.   1.原型对象 (1)当创 ...

  4. javascript原型模式理解

    传统的面向对象语言中,创建一个对象是通过使用类来创建一个对象的,比如通过类飞行器来创建一个对象,飞机. 而js这种没有类概念的动态设计语言中,创建对象是通过函数来创建的,所以通常也把js称为函数式语言 ...

  5. JavaScript原型模式-理解对象

    一:简述 当初学编程一看到什么什么模式就比较头晕,不过本文我们通过简单的示例代码来说一下js 对象这个话题 ,来看下如何理解这个原型模式. 二:理解对象 1.简单对象 js对象中没有java.C#等类 ...

  6. JavaScript原型模式(prototype)

    1.原型是一个对象,其他对象可以通过它实现属性的继承所有对象在默认的情况下都有一个原型,因为原型的本身也是对象,所以一个类的真正原型是被类的内部[prototype]属性所指出.每个函数都有一个属性叫 ...

  7. JavaScript设计模式-3.原型模式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. 初涉JavaScript模式 (7) : 原型模式 【三】

    组合使用构造函数模式和原型模式 上篇,我们提到了原型模式的缺点,就是每个实例不能拥有自己的属性,因为纯原型模式所有的属性都是公开给每个实例的,故我们可以组合使用构造函数模式和原型模式.构造函数用来定义 ...

  9. [设计模式] JavaScript 之 原型模式 : Object.create 与 prototype

    原型模式说明 说明:使用原型实例来 拷贝 创建新的可定制的对象:新建的对象,不需要知道原对象创建的具体过程: 过程:Prototype => new ProtoExam => clone ...

随机推荐

  1. 深入理解php底层:php生命周期 [转]

    1.PHP的运行模式: PHP两种运行模式是WEB模式.CLI模式.无论哪种模式,PHP工作原理都是一样的,作为一种SAPI运行. 1.当我们在终端敲入php这个命令的时候,它使用的是CLI. 它就像 ...

  2. spring知识大全(4)

    5 Spring对事务的支持 一.AOP事务的含义: 事务当作一个切面,动态地织入到目标对象,形成一个代理对象. 二.Spring的事务机制 Spring支持声明式事务. Spring使用事务服务代理 ...

  3. ADO.net操作数据库

    今天整理硬盘,发现2年前开始着手开始学习C#的学习日记.陆续整理,一是自己的知识梳理梳理,二是希望与大家多多交流,能给初学者带来一定帮助,当然是更高兴的啦. 断线对象 另一类是与数据源无关的断线对象, ...

  4. jQuery外链新窗口打开

    对于外链,为了留住用户在本站,我们通常会使用新窗口打开,你可以设置target="_blank".然而手动一个是麻烦,另一个则是有可能会遗漏,本文通过jQuery查询要点击的链接, ...

  5. HTML流动布局各种宽度自适应

    <!DOCTYPE html> <html lang="en"> <style> html,body{ padding: 0;margin: 0 ...

  6. Block循环引用问题研究

    自从苹果在objc中添加Block功能支持以后已经过了很久.目前网上对于Block的使用有很多介绍.不过对于Block的内存管理问题,则是众说纷纭.再加上objc开始使用ARC以后,对于Block的内 ...

  7. 一台MySQL服务器启动多个端口

    一台MySQL服务器启动多个端口 在测试Mysql多主一从服务器,即一个从服务器多端口同步不同主库.本文记录了开启不同端口的操作. 详细步骤: 1.首先要先把my.cnf配置文件复制一份,开几个端口要 ...

  8. HTTP版本进化过程

    http版本之间的区别以及变化过程[更新中...]

  9. 丙申年把真假美猴王囚禁在容器中跑 ASP.NET Core 1.0

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  10. 黑马程序员-nil Nil NULL NSNull 野指针和空指针

    空指针1.空指针指不含有任何内存地址的指针.在没有具体初始化之前,其被符值为0Dog * dog = nil;Dog * dog = NULL;都为空指针2.野指针指指向的内存为垃圾内存,导致其值不确 ...