专栏首页coding for loveJS进阶系列01-JS的弱类型和动态类型

JS进阶系列01-JS的弱类型和动态类型

1. 弱类型,强类型,动态类型,静态类型的区别

首先,我们要弄清楚编程语言的两组划分,即弱类型和强类型,动态类型和静态类型。下面有一幅图,非常详细地说明了它们各自的定义和区别。

动态/静态,强类型/弱类型-转

该图转自编程语言傻傻分不清:弱类型、强类型、动态类型、静态类型一文,大家可以前往该文章查看编程语言这两组划分的详细定义和区别。

2. JS的弱类型和动态类型

JS种有5种基本数据类型:Undefined,Null,Boolean,Number和String,以及一种复杂数据类型Object。但JS的变量在声明时无需指定其类型,而是统一使用var关键字。并且在其声明之后,我们可以为其随便赋值不同的类型。 JS由于不需要关注变量的类型,可以使代码更加简洁,也能使开发者集中更多的精力在处理业务逻辑之上。但由于其无法保证变量类型,从而在程序运行期可能发生跟类型相关的错误。 比如:

var s = 1;
s();  //Uncaught TypeError: s is not a function

而这样的错误对于JAVA在编译期间就会检查出来。

3. JS鸭子类型的思想

(这一节的内容大家可以直接看BOOK-《JavaScript设计模式与开发实践》 第一部分)

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

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

有个很形象的例子:

从前在Javascript王国里,有一个国王,他觉得世界上最美妙的声音就是鸭子的叫声,于是国王召集大臣,要组建一个1000只鸭子组成的合唱团。大臣们找遍了全国终于找到999只鸭子,但是始终还差一只,最后大臣发现一直特别的鸡,它的叫声跟鸭子一模一样,于是这只鸡就成为了合唱团的最后一员。

这个故事告诉我们,国王要听的只是鸭子的叫声,这个声音的主人到底是一个鸡还是要鸭子并不重要。鸭子类型指导我们只关注对象的行为,而不关注对象本身,也就是关注HAS-A(拥有什么),而不是IS-A(是什么)。

下面我们用代码模拟这个故事:

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);

我们看到,对于加入合唱团的动物,大臣们根本无需检查它们的类型,而是只需要保证它们拥有duckSinging方法。如果下次期望加入合唱团的是一只小狗,而这只小狗刚好也会鸭子叫,我相信这只小狗也能顺利加入。

在动态类型语言的面向对象设计中。鸭子类型的概念至关重要。利用鸭子类型的思想,我们不必借助超类型的帮助,就能轻松地在动态类型语言中实现一个原则:“面向接口编程,而不是面向实现编程”。例如,一个对象若有push和pop方法,并且这些方法提供了正确的实现,它就可以被用来当作栈使用。一个对象如果有了length属性,也可以依照下标来存取属性(最好还要拥有slice和splice等方法),这个对象就可以被当做数组来使用。

参考

编程语言傻傻分不清:弱类型、强类型、动态类型、静态类型 BOOK-《JavaScript设计模式与开发实践》 第一部分

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ES6常用新特性学习1-let和const

    在ES6以前,变量的声明都是使用var关键字,且会进行变量声明提升。另外,我们曾经讲过,JS中是没有块级作用域的,这一点也带来了很多的不便。ES6 新增了let...

    love丁酥酥
  • JS进阶系列

    在JS入门难点解析系列中,我们对JS的一些重要概念,比如:作用域,作用域链,原型,原型链,继承,活动对象,this,执行环境,变量声明,函数声明等进行了详细的分...

    love丁酥酥
  • JS进阶系列03-JS面向对象的三大特征之多态

    多态是同一个行为具有多个不同表现形式或形态的能力。在JAVA中,多态通过在子类中重写父类方法去实现。但是在JS中,由于JS本身是动态的,天生就支持多态。大家可以...

    love丁酥酥
  • 使用openSSL构造一个支持https的nodejs服务器

    首先通过下面的链接下载openSSL https://slproweb.com/products/Win32OpenSSL.html

    Jerry Wang
  • 使用CNVkit进行CNV分析

    CNVkit是一款CNV预测软件,适用于全外显子,目的区域靶向测序等数据的CNV检测,官网如下

    生信修炼手册
  • Android网络访问库 - Retrofit学习(1)基础

    Retrofit是一个类型安全的HTTP客户端,支持Android和Java.它是Square公司开源的项目,当前版本2.0。

    zhangyunfeiVir
  • 回调函数路由,模板渲染

    祈澈菇凉
  • cocos2d怎么设置屏幕朝向?横屏 or 竖屏设置

    在Cocos引擎里面找了好久,没找到相关接口,网上也搜索了好久,最后发现,原来需要根据各个平台分别进行设置。 Android 修改项目根目录 proj.andr...

    _gongluck
  • 拼智商,谷歌、苹果、微软、亚马逊的AI助手谁赢了?有些结果没料到

    导读:Loup Ventures近日发布了“年度数字助理智商测试”,跟踪智能手机上四大AI助手的表现。该公司表示,Google的Assistant,Apple的...

    华章科技
  • Jdk_API——1.8和Jdk_API1.6下载分享

    链接:https://pan.baidu.com/s/1bZKfldtqjCOsaYaT1Q9RcQ 提取码:t9ad

    泰斗贤若如

扫码关注云+社区

领取腾讯云代金券