Javascript原型模式总结梳理

  在大多数面向对象语言中,对象总是由类中实例化而来,类和对象的关系就像模具跟模件一样。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设计模式与开发实践》

时间: 2024-10-26 19:42:04

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

JavaScript原型模式

一.提到原型模式,和构造函数关系密切,先讲一下它 javascript没有类,通过函数来模拟实现类,用new来创建对象,函数内部的this指针来指向调用它的对象. 事例中创建对象myGril,这个对象就获取了构造函数内this指向的所有属性和方法. var GirlFriend=function (temperament) { this.temperament=temperament; this.loseTemper=function(){ return "When angry:"+t

Javascript:原型模式类继承

原型模式 每个函数(准确说不是类.对象)都有一个prototype属性,这个属性是一个指针,指向一个对象. 使用原型对象的好处是可以让所有对象实例共享它包含的属性和方法. 1.原型对象 (1)当创建一个新函数,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象. (2)默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向 prototype属性所在函数  的指针. (3)实例的内部包含一个指针,叫[[Prototype]].不过

javascript原型模式发展历程

// 工厂模式 function Person(name,age){ var o = new Object(); o.name=name; o.age=age; o.sayName=function(){ alert(o.name) } return o } var o1=Person('lele',5) var o2=Person('mama',31) // 构造函数模式(能够标识对象属于哪一种类型,但是函数没有复用) function Person(name,age){ this.name=

javascript原型模式(枚举对象的属性)

1.理解原型对象 function Person() { } Person.prototype.name = "Nicholas"; Person.prototype.age = 28; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () { alert(this.name); }; var person1 = new Person(); person1

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

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>js高级语法3-原型模式 </title> 6 </head> 7 <body> 8 <script> 9 /* 10 javascript原型模式(prototype): 11 1. 原型是一个对象,其他对象可以通过它实现属性的继承,所有的

javascript中的模式解析——原型模式

理解原型模式,首先要理解prototyoe(这个单词翻译 原型)属性,<javascript高级程序设计>书中描述到——我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法. 我在上一篇构造函数模式所说的,我们构建了一个一个Person函数,然后通过new一个person函数来创建了person1实例,person2实例,既然每个函数都有一个prototype属性,那么我有几个问题想要弄明白: per

理解javascript中的原型模式

一.为什么要用原型模式. 早期采用工厂模式或构造函数模式的缺点:  1.工厂模式:函数creatPerson根据接受的参数来构建一个包含所有必要信息的person对象,这个函数可以被无数次的调用,工厂模式尽管解决了创建多个相似对象的问题,却没有解决对象识别的问题(返回的是自定义的一个对象o,不明确对象o的类型).  2. 构造函数模式:构造函数的调用和其他oo语言一样,用new操作符来构建一个Person的实例:javascript中的构造函数也是函数(所以也可以直接像普通函数那样直接调用方法名

JavaScript 面向对象 (prototype 原型模式)

一. JavaScript 设计思想 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.这是历史上第一个比较成熟的网络浏览器,轰动一时.但是,这个版本的浏览器只能用来浏览,不具备与访问者互动的能力.比如,如果网页上有一栏"用户名"要求填写,浏览器就无法判断访问者是否真的填写了,只有让服务器端判断.如果没有填写,服务器端就返回错误,要求用户重新填写,这太浪费时间和服务器资源了. 因此,网景公司急需一种网页脚本语言,使得浏览器可以与网页互动.工程师_Brend

Javascript 构造函数模式、原型模式

前两天写完组合继承,打算总结一下原型继承的,不过今天看了一下工厂模式.构造函数模式和原型模式,觉得有必要总结一下以加深印象. ——————————————————————————————————————————————————————————————————————————————————碎碎念. 1.工厂模式 <Javascript 高级程序设计(第3版)> 用了寥寥十多行介绍了工厂模式.我找了一些相关资料,想确定一下这种模式的具体适用场景和优势.按照资料中的说法,是考虑到 ECMAScri