• (一)面向对象的javascript


    javascript是一门典型的动态类语言

    一:鸭式辨型(指导我们关注对象的行为,而不关注对象本身)。

        var duck = {
            duckString: function(){
                console.log("嘎嘎")
            }
        };
    
        var chicken = {
            duckString: function(){
                console.log("嘎嘎")
            }
        }
    
        var choir = []; //合唱团
        
        var joinChoir = function( animal ){
            if (animal && typeof animal.duckString === 'function') {
                choir.push(animal);
                console.log('恭喜加入合唱团')
                console.log('合唱团已经有的数量:'+ choir.length)
            }
        }
    
        joinChoir(duck)
        joinChoir(chicken)

    对于加入合唱团,无需关心他们的类型,而只是确保它有duckString方法。

    二:多态

    多态的实际含义是,同一操作作用于不同的对象上面,可以产生不同的解释,执行不同的结果。 (实际上是把“做什么”和“谁去做”分离开来)

        var makeSound = function( animal ) {
            if ( animal instanceof Dcuk) {
                console.log("嘎嘎")
            } else if ( animal instanceof Chiken) {
                console.log("咯咯")
            }
        }
    
        var Dcuk = function(){};
        var Chiken = function(){};
    
        makeSound(new Dcuk)
        makeSound(new Chiken)

    (1多态的度复杂性

        var makeSound = function( animal ) {
            animal.sound()
        }
    
        var Dcuk = function() {};
        var Chiken = function() {};
        var Dog = function() {};
    
        Dcuk.prototype.sound = function() {
            console.log("嘎嘎嘎")
        }
    
        Dog.prototype.sound = function() {
            console.log("汪汪汪")
        }
    
        makeSound(new Dcuk)
        makeSound(new Dog)

    将行为分享在各个对象中,并让这些对象各自负责自己的行为,这正是面向对象优点

    假设我们要编写一个地图应用,现在有两家可选的地图api提供商供我们接入自己的应用。目前我们选择谷歌地图,谷歌地图中提供show()方法,负责在页面上展示整个地图。

        var googleMap = {
            show: function() {
                console.log('开始渲染地图')
            }
        }
    
        var renderMap = function() {
            googleMap.show()
        }
    
        renderMap()

    后来因为某些原因,我们要将谷歌地图转化为百度地图,为了让renderMap函数保持一定的弹性,我们使用一些条件分支来让renerMap函数同时支持谷歌地图和百度地图

        var googleMap = {
            show: function() {
                console.log("渲染谷歌地图")
            }
        }
    
        var baiduMap = {
            show: function() {
                console.log("渲染百度地图")
            }
        }
    
        var renderMap = function( type ){
            if ( type === 'google') {
                googleMap.show()
            } else if ( type === 'baidu') {
                baiduMap.show()
            }
        }
    
        renderMap('baidu')
        renderMap('google')

    虽然renderMpa函数保持了一定的弹性 ,但是这种弹性是很脆弱的,一旦替换成搜狗地图,那无疑需要改动renderMap()函数,继续往里边堆砌条件分支语句。

        var renderMap = function ( map ){
            if (map.show instanceof Function) {
                map.show();
            }
        }
    
        var sosoMap = {
            show: function() {
                console.log("搜搜地图开始渲染")
            }
        }
        renderMap(googleMap)
        renderMap(baiduMap)
        renderMap(sosoMap)

    现在我们来找找这段代码的多态性,当我们向谷歌地图对象和百度地图对象发出“展示地图的”请求时。会分别调用他们的show()方法。会产生不同的执行结果。对象的多态性提示我们,“做什么”和“怎么去做”是可以分开的,即使以后增加了搜搜地图,renderMap函数任然不需要做出什么改变。

    三 封装

    封装的目的是将信息隐藏,一般而言,我们讨论的封装是封装数据和封装实现。
    这里我们将说明下更广义的封装,不仅包括封装数据和封装实现,还包括封装类型和封装变化

    1。封装数据
    在许多语言的对象系统中,封装数据是由语法解析实现的,这些语言提供了private, public, protected等关键字来提供不同的访问权限

    javascript没有提供对这些关键字的支持,我们只能依赖变量的作用域来实现封装特性,而且只能模拟出public,private这两种封装。

    除了ES6的let之外,我们一般通过函数来创建作用域。

        var myObject = (function() {
            var _name = 'seven'; //私有private变量
            return {
                getName : function() { //公开public变量
                    return _name; 
                }
            }
        })();
    
        console.log(myObject._name) ;//undefined
        console.log(myObject.getName()) ;//seven

    另外,在ES6中,还可以通过Symbol创建私有属性

    四:使用克隆的原型模式

    如果使用原型模式,我们只需要负责克隆的方法,变能完成同样的功能。
    原型模式使用的关键,是语言本身是否提供了克隆的方法,ES5提供了Object.create方法,代码如下

        var Plane = function() {
            this.blood = 100;
            this.attackLevel = 1;
            this.defenseLevel = 1;
        };
    
        var _plane = new Plane()
        _plane.blood = 500;
        _plane.attackLevel = 2;
        _plane.defenseLevel = 2;
    
        var clonePlane = Object.create( _plane );
        console.log( clonePlane ) // {blood: 500, attackLevel: 2, defenseLevel: 2}
    
        //不支持Object.create方法的浏览器中,可以使用以下代码
        Object.create = Object.create || function( obj ) {
            var F = function() {};
            F.prototype = obj;
    
            return new F();
        }

    原型继承

    在javascript语言里,我们并不关心克隆的细节,因为这是引擎内部实现的。我们只是显式的调用
    var object1 = new Object()或者 var object2 = {};此时,引擎内部会从Object.protype上面克隆出一个对象来,我们最终得到的就是这个对象。

    我们看看通过new运算符从构造器中得到一个对象,下面的代码最熟悉不过了。

        function Preson( name ) {
            this.name = name;
        }
        var a = new Preson("seven2");
        console.log(a.name) //seven2
    
        Preson.prototype.getName = function() {
            return this.name
        }
    
        console.log(a.getName()) //seven2

    对象会记住它的原型。

        var b = new Object();
        console.log(b.__proto__ === Object.prototype) ;//true

    附上我们最常用的原型继承方式

        var obj = {name:'seven3'};
        var A = function(){};
        A.prototype = obj; //{name:'seven3'};
        var aa = new A()
        console.log(aa.name)

    我们常期望一个类继承另外一个类时 ,往往使用以下代码来模拟

      var AA = function() {};
      AA.prototype = {name:"seven4"}
    
      var BB = function() {};
      BB.prototype = new AA()
    
      var bb = new BB();
      console.log(bb.name);//seven4
  • 相关阅读:
    将一个dropdownlist从一个div复制到另一个div
    【转】AOP 那点事儿(续集)
    【转】AOP 那点事儿
    spring 简单配置
    spring 基础原理
    jvm简介
    jre、jdk和jvm的关系
    【转】Jvm工作原理
    servlet简述
    Filter简述
  • 原文地址:https://www.cnblogs.com/ahthw/p/5071569.html
Copyright © 2020-2023  润新知