• 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设计模式与开发实践》

  • 相关阅读:
    sql语句添加查询字段
    SqlServer Case when then用法总结
    单例与多线程
    HttpSession详解
    范式
    SQL语句中的Having子句与where子句
    HTTP无状态
    字节流与字符流的区别
    选择排序
    ReentrantLock VS synchronized
  • 原文地址:https://www.cnblogs.com/dojo-lzz/p/4542943.html
Copyright © 2020-2023  润新知