面向对象的JavaScript

本文探讨了JavaScript中鸭子类型的概念及其实现,并通过具体示例介绍了如何利用多态性来提高代码的灵活性和扩展性。

一.鸭子类型

在JavaScript中,当我们对一个变量进行赋值时,显示不需要考虑它的类型,因此,JavaScript是一门典型的动态类型语言。

动态类型语言对变量类型的宽容实际给编码带来了很大的灵活性。由于无需进行类型检测,我们可以尝试调用任何对象的额任意方法,而无需去考虑它原本是否被设计为拥有该方法。

这一切都建立在鸭子类型的概念上,通俗说法是:“如果它走起路来像鸭子,叫起来也是鸭子,那么它就是鸭子。”

用代码来模拟:

var duck = {
            duckSinging: function () {
                console.log("嘎嘎嘎");
            }
        };

        var chicken = {
            duckSinging: function () {
                console.log("嘎嘎嘎");
            }
        };

        var choir = [];  // 合唱团

        var joinChoir = function (animal) {
            if (animal && typeof animal.duckSinging === 'function') {
                choir.push(animal);
                console.log("恭喜加入合唱团");
                console.log("合唱团已有成员数量:" + choir.length);
            }
        };

        joinChoir(duck);
        joinChoir(chicken);
在动态类型语言的面向对象设计中,鸭子类型的概念至关重要。
二.多态

实际含义是:同一操作作用于不同的对象上,可以产生不同的解释和不同的执行结果。

一段“多态”的js代码

var Duck = function () {};
        var Chicken = function () {};

        var makeSound = function (animal) {
            if (animal instanceof Duck){
                console.log("嘎嘎嘎");
            }else if (animal instanceof Chicken){
                console.log("咕咕咕");
            }
        };

        makeSound(new Duck());
        makeSound(new Chicken());
这段代码确实体现了“多态性”,但这样的多态性无法令人满意,若后来又增加了一只动物,比如狗,狗的叫声是“汪汪汪”,此时我们必须要改动makeSound函数,这样是不好的。

多态背后的思想是将“做什么”和“谁去做以及怎样去做”分离开来,也就是将“不变的事物”与“可能改变的事物”分离开来。在以上代码中,动物都会叫这是不变的,不同类型的动物怎么叫是可变的。把不变的隔离出来,把可变的部分封装起来。

下面是改写后的代码,首先我们把不变的部分隔离出来,那就是所有动物都会发出叫声:

var makeSound = function (animal) {
            animal.sound();
        };
然后把可变的部分各自封装起来:

var makeSound = function (animal) {
            animal.sound();
        };

        var Duck = function () {};
        Duck.prototype.sound = function () {
            console.log("嘎嘎嘎");
        };

        var Chicken = function () {};
        Chicken.prototype.sound = function () {
            console.log("咕咕咕");
        };

        makeSound(new Duck());
        makeSound(new Chicken());
若又增加了一只狗,只需要简单的追加一些代码即可,不需改动以前的makeSound函数。

var Dog = function () {};
        Dog.prototype.sound = function () {
            console.log("汪汪汪");
        };
makeSound(new Dog());
再看一个例子,假设我们要编写一个地图应用,现在有两家可选的地图API提供商供我们借入自己的应用。目前我们选择的是谷歌地图,谷歌地图的API中提供了show方法,负责在页面上展示整个地图。(示例代码如下)
var googleMap = {
            show: function () {
                console.log("开始渲染谷歌地图");
            }
        };

        var renderMap = function () {
            googleMap.show();
        };

        renderMap();
后来因为某些原因,要把谷歌地图换成百度地图,为了让renderMap函数保持一定的弹性,我们用一些分支来让renderMap函数同时支持谷歌地图和百度地图:

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('google');
        renderMap('baidu');
可以看到,虽然renderMap函数目前保持了一定的弹性,但这弹性很脆弱,一旦需要替换成其他地图,只能改动renderMap,继续往里面堆砌条件分支语句。

我们还是先把程序中相同的部分抽象出来,那就是显示某个地图:

var googleMap = {
            show: function () {
                console.log("开始渲染谷歌地图");
            }
        };

        var baiduMap = {
            show: function () {
                console.log("开始渲染百度地图");
            }
        };

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

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

 var sosoMap = {
            show: function () {
                console.log("开始渲染搜搜地图");
            }
        };
renderMap(sosoMap);








考虑可再生能源出力不确定性的商业园区用户需求响应策略(Matlab代码实现)内容概要:本文围绕“考虑可再生能源出力不确定性的商业园区用户需求响应策略”展开,结合Matlab代码实现,研究在可再生能源(如风电、光伏)出力具有不确定性的背景下,商业园区如何制定有效的需求响应策略以优化能源调度和提升系统经济性。文中可能涉及不确定性建模(如场景生成与缩减)、优化模型构建(如随机规划、鲁棒优化)以及需求响应机制设计(如价格型、激励型),并通过Matlab仿真验证所提策略的有效性。此外,文档还列举了大量相关的电力系统、综合能源系统优化调度案例与代码资源,涵盖微电网调度、储能配置、负荷预测等多个方向,形成一个完整的科研支持体系。; 适合人群:具备一定电力系统、优化理论和Matlab编程基础的研究生、科研人员及从事能源系统规划与运行的工程技术人员。; 使用场景及目标:①学习如何建模可再生能源的不确定性并应用于需求响应优化;②掌握使用Matlab进行商业园区能源系统仿真与优化调度的方法;③复现论文结果或开展相关课题研究,提升科研效率与创新能力。; 阅读建议:建议结合文中提供的Matlab代码实例,逐步理解模型构建与求解过程,重点关注不确定性处理方法与需求响应机制的设计逻辑,同时可参考文档中列出的其他资源进行扩展学习与交叉验证。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值