javascript设计模式-原型模式

多态

      var goolgMap = {
            show: function () {
                console.log('显示谷歌地图');
            }
        }

        var sosoMap = {
            show: function () {
                console.log('显示搜搜地图')
            }
        }

        var baidu = {
            show: function () {
                console.log('显示百度地图');
            }
        }

        function renderMap(map) {
            if (map.show instanceof Function) {
                map.show();
            }
        }

        renderMap(sosoMap);
        renderMap(goolgMap);
        renderMap(baidu);

在这个例子中,我们假设每个地图 API 提供展示地图的方法名都是 show,在实际开发中也许不会如此顺利,这时候可以借助适配器模式来解决问题。 (适配器模式) 做什么(公共的部分进行封装) 谁去做(不同的部分封装为不同的类)

实现了私有属性和公共方法

        //这里是一个闭包
        var myObj = (function () {
            var name = 'sven'; //这里形成了一个私有的属性
            return {
                getName: function () { //这里是一个公共的方法
                    console.log(name);
                }
            }
        })();
 console.log(myObj.getName()); //输出了name
 console.log(myObj.name); //输出的undefined;
        //原型模式
        var Plane = function () {
            this.blood = 100;
            this.attacklevel = 1;
            this.defenselevel = 1;
        }

        var plane = new Plane;
        plane.blood = 500;
        plane.attacklevel = 100;
        plane.defenselevel = 200;

        var clonePlane = Object.create(plane);
        console.log(clonePlane); //使用克隆的原型模式 克隆是创建对象的手段

事实上,JavaScript 中的根对象是 Object.prototype 对象。Object.prototype 对象是一个空的对象。我们在 JavaScript 遇到的每个对象,实际上都是从 Object.prototype 对象克隆而来的, Object.prototype 对象就是它们的原型。比如下面的 obj1 对象和 obj2 对象

        var obj1 = new Object();
        var obj2 = {};
        console.log(Object.getPrototypeOf(obj1) === Object.prototype);
        console.log(Object.getPrototypeOf(obj2) === Object.prototype);

原型链
对象->proto- ->Constructor.prototype ->Object.prototype;
每个对象都有一个隐藏属性_proto_ 某个对象的__proto__属性默认会指向它的构造器的原型对象即{Constructor}.prototype __proto__就是对象跟“对象构造器的原型”联系起来的纽带对象构造器的原型并不仅限于Object.prototype 上,而是可以动态指向其他对象
原型链继承
正是因为构造器的原型并不仅限于 Object.prototype 上,而是可以动态指向其他对象从而产生了原型链继承的方式
这样一来,当对象 a 需要借用对象 b 的能力时,可以有选择性地把对象 a 的构造器的原型指向对象 b,从而达到继承的效果。下面的代码是我们最常用的原型继承方式

        var obj = { name: 'sven' };
        var A = function () { };
        A.prototype = obj;//A的构造器原型指向了obj对象从而达到继承的效果
        var a = new A();
        console.log(a.name); //输出了sven

执行上面的代码引擎做哪些事情首先,尝试遍历a对象所有属性,但没有name属性查找name属性的这个请求委托给对象a的构造器的原型,它被a._proto_记录并且指向了A.prototype,而A.prototype被设置为对象obj。在obj中找到了name属性,并且返回它的值

        var A = function () { };
        A.prototype = { name: 'sven' };
        var B = function () { };
        B.prototype = new A();
        var b = new B();
        console.log(b.name);

最后还要留意一点,原型链并不是无限长的。现在我们尝试访问对象 a 的 address 属性。而对象 b 和它构造器的原型上都没有 address 属性,那么这个请求会被最终传递到哪里呢?实际上,当请求达到 A.prototype,并且在 A.prototype 中也没有找到 address 属性的时候,请求会被传递给 A.prototype 的构造器原型 Object.prototype,显然 Object.prototype 中也没有address 属性,但 Object.prototype 的原型是 null,说明这时候原型链的后面已经没有别的节点了。所以该次请求就到此打住,a.address 返回 undefined。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值