JavaScript语言核心(一)——类型、变量和值
知识点:
1. JS的类型分类:基本类型、对象类型。
2. 基本类型:数字、文本、布尔值、null、undefined
3. 对象类型:全局对象、包装对象、对象、数组、函数。
这一章算是JS的最基本的章节了。原书对这一章讲解的很详细,也讲了很多细节性的东西。下面从Java的角度进行下对比和总结。
1.基本数据类型:
我们都知道Java的基本数据类型有8类: byte / short /int /long/ float/ double/char /boolean. 。Java对基本数据类型分的很细,相比Java,JS的区分就没那么严格了,只有5类: number/string/Boolean/null/undefined。
(2) null:首先JS中null是关键字,这点JS和Java中一样。但是JS中null是一个特殊的“对象值”。JS中对null执行tepeof返回的是Object,但是执行null instanceofObject,返回的是false,在Java中对null执行instanceof也是false。
PS:其实说这么多,其实就是想说在JS中null是一个基本数据类型,在Java中和JS中对null值进行if判断都是false!上面的都忘记,记住这个就行了!
(3) Undefined:这个是JS中一个另类的空值,基本上所有由JS编译器赋值的变量都会被赋予undefined的这个值,这个值一般不应该出现在我们的JS程序中。在Java中没有这么一个特殊的值,因为Java是强语言,JS是弱语言。
(4) 数字:JS对数字区分不明显,没有精度一说。但是Java中对数字精度有明确的区分。不过JS和Java在记录浮点型数据(float和double)的时候都使用的是IEEE-754的二进制表示法。这几乎是现代所有编程语言都采用的表示法,这种表示法可以很精确的表示分数,但是这种表示法在表示十进制分数的时候是有问题的(Java和JS一样都有问题,以前真没注意过!)。比如不管在Java中还是在JS中,我们试试运行下下面的代码:
//下面的代码Java中和JS中一样
X = 0.2 -0.1
Y = 0.3 – 0.2
X == y // 结果:false
X== 0.1 //结果:true 0.2-0.1=0.1
Y == 0.1 //结果:false 0.3 – 0.2 != 0.1
另外,和Java一样,在JS中也有NaN和Infinity。NaN是Not a Number的缩写,Infinity表示无穷大,我们都知道在高等数学中一个数除以0是被定义为无穷大的,在初等数学中这是非法的。我们都知道Java中如果是double和float类型的运算,除以0会返回Infinity,如果是int类型的运行除以0会报错。如:
//下面的是Java代码
float data = 100.0f / 0.0f; //infinity
double data = 100.0 / 0.0; // infinity
int data2= 1 / 0; // 报错:java.lang.ArithmeticException: / by zero
下面的表是Java和JS中运算的一些规则:
预算规则
|
Java
结果
|
JS
结果
|
说明
|
普通加减乘数 | 变量对应的数据类型 | number | 在Java中数据类型不对会编译不过去。JS没有类型检查。 |
一个数除以0 | 浮点型:Infinity,整型:报错 | infinity | |
0除以0 | 浮点型:NaN,整型:报错 | NaN | |
正数除以0 | 浮点型:Infinity,整型:报错 | Infinity | |
负数除以0 | 浮点型:-Inifity,整型:报错 | -Infinity | |
数据上溢 | 浮点型:Infinity,整型:呵呵。 | Infinity | Java整型:自己测试! |
数据下溢 | 浮点型和整型:都返回0 | 0 |
|
备注:数据上溢:超出程序可以表示的最大值。数据下溢:表示一个数太接近0,无法精确表示。平时所说的超出数据的最大值和最小值都属于数据上溢。
PS:基本上面大部分向对象语言都有基本数据类型,这是平时编程中最常用的也是用的最多的,基本数据类型有很多很小的细节问题,我们没必要要求自己强制记住,如果理解不了,那就到实际项目中体验,我想调试过一两次就应该记忆深刻了!如果发生财务类的数据溢出,嘿嘿,都是钱啊,相信大家会“记忆犹新”的!!哈哈!!
另外:NaN、null和undefined,在JS中这三个是比较特殊的数据类型。null并不是js默认的值,换句话说,如果java中定义了一个引用变量,变量没赋值,那么变量就是null,但是js中这种情况是undefined。Undefined表示是所有数据未赋值时的初始值。或者可以说null是js留给我们程序用的,表示把变量置空。Undefined是js系统级的,是不被期望的。
我们可以用下面的表来记忆JS的基本数据类型和Java中数据类型的关系:
Java类型 | 对应JS类型 |
说明
|
byte |
number
| Java包装器:Byte,父类:Number |
short | Java包装器:Short,父类:Number | |
int | Java包装器:Integer,父类:Number | |
long | Java包装器:Long,父类:Number | |
float | Java包装器:Float,父类:Number | |
double | Java包装器:Double,父类:Number | |
char | string | Java包装器:Charset,父类:Object |
string | Java中string不是基本类型,父类:Object | |
boolean | boolean | Java包装器:Boolean,父类:Object |
上面的转换表,在服务器端JSON数据输出的时候很有用,利用Java泛型可以很方便的实现Java对象到JS对象的转换。
2.对象类型:
2.1概述——本质:
在java中对象类型可以分为类类型和应用数据类型两种而且这两种制式我们平时自己区分的,Java中对象很好辨认!但是JS中对于对象类型的区分就有点细了:对象类型、数组类型、函数。书中对于对象类型并没有明确的区分出来,上面的分类仅仅是我个人的一个总结。但是《JavaScript权威指南》中明确指出了,它们本质上都是对象。
var coder = {
"id" : 1,
"name" : "saillen"
}
JS的对象更像是Java的中Map,是由key :value格式组成的。JS中对象属性的名称以字符串形式存储,即使我们使用标识符(也就是变量)或者是数字啥的,最终JS编译器都会帮我们翻译为字符串的,这点以后讲函数的时候会非常有用!
JS对象的属性值可以是Object类型或者是基本类型的任意一种,也就是说值在js中是什么都可以,均不会出现错误(使用的时候要自己当心,明确好自己用的什么类型的数据)。
Java中的对象是通过new得到的。JS的对象本质上也是通过new关键字得来的,但是JS的对象也可以不通过new关键字获得,如通过对象直接量,也就是直接给变量赋值,值是一个对象写法,就像上面似的。
其实造成Java和JS的这种区别的原因在于,Java是一种强类型的语言,它需要经过严格的编译,编译期间它会检查数据的类型,所以对象需要定义一个结构,也就是类。
而JS是弱类型的语言,它只有预编译,预编译期间会定义变量,而赋值是在执行的时候赋值的,所以对象可以没有结构定义,比如
var coder = {
"id" : 1,
"name" : "saillen"
}
var coder = new Object_1();
function Object_1(){
}
Object_1.prototype = {
"id" : 1,
"name" : "saillen"
}
另外JS中对象虽然说也可以包含方法,但那只是一种习惯上的叫法,因为方法就是函数,而函数也是一个对象,所以js中的对象本质上说只有属性,方法就是可以执行的属性,方法在预编译节点是把要执行的语言当成属性值存储的!
2.2对象类型——普通对象:
关于JS的对象,上面提到可以分为三类,对象类型,数组类型,函数。对象类型又可以细分为全局对象、包装对象、普通对象三类。
普通对象有三种构造方法:
(1)通过花括号{}:这是我们经常用的,JSON数据格式就是这种结构的对象;
(2)通过newObject():构造的时候可以传入很多东西,这些细节,不求甚解,多用多查就明白了。(装逼的感觉就是爽,说实话,我只是没记住而已= =,new Object传入不同的参数,获得的对象类型也不同,有兴趣的自己找谷老师问问吧。)
(3)通过new ClassName():上面的Object是JS的保留关键字这里的ClassName是我们自己构造的类的名称,使用这种方式一定要先定义“类”。这种构造方法非常接近Java的用法,对于Java的熟悉的童鞋肯定也明白这个实例化流程,无法就是new操作调用了构造方法,返回了对象本身,构造方法不能有返回值。这好像已经是面向对象编程语言的不成文规定了。不过,JS中的构造方法可以有返回值。
2.2对象类型——包装对象:
普通对象的更多内容,在后面的对象章节有介绍,下面说下包装类型。
包装类型:我们都知道在java中每个基本类型都对应了一个封装类型,并且java(不只是java,应该是面向对象语言都有吧?)有著名的自动装箱拆箱机制。JS也一样,这里的包装类型就是JS的基本类型对应的对象类型:Number,String,Boolean。JS同样会自动将基本数据类型装箱、拆箱,具体的装箱、拆箱规则和Java比较类型,不详细说了,知道那么多也不好!名侦探柯南里大多数的死者不就是知道的太多了嘛!!!
2.2对象类型——全局对象:
全局对象:我们都知道有全局肯定有局部,JS是被JS解释器运行的(这当然是废话,就像Java由JVM运行一样),JS解释器会在启动的时候初始化一个全局对象,然后给全局对象的属性赋值,全局对象的属性主要有四类:
全局属性:undefined等
全局函数:isNaN()等
构造函数:Date()等
全局对象:Math,JSON等
其实我们可以说我们的代码都是运行在全局对象中的,就好像是Java的代码都会有一个System环境一样,JS的代码也是有运行环境的,这些环境的属性可以从全局对象中获得。
总结:
关于JS基本数据类型和对象笔记做的比较细,因为我认为这是基础,学Java的时候基础学的就不是很好,很多Java细节有的时候猛然被问到都想不起来,对于JS这类弱语而言基础的学习更应该扎实。正因为JS本身并没有多少API,我们常用的什么jQuery库啊,都是“民间组织”,不是正统,基础搞不好,很难登堂入室的。而且JS本身没有什么IDE可用,所以开发效率很大看个人基础!
在我看来,JS这类弱语言更像是《笑傲江湖》中华山“气宗”,花大力气打好基础,后面的招式就得心应手。而Java这类强语言更像是华山“剑宗”,剑宗没有扎实的“气”也是能学好的,因为招式在那里呢,不对的话有人提醒,外加其他“宝剑”(IDE)的帮助,强语言编程中很多问题是不会犯的。