有一种说法叫做“空杯理论”(就是那个著名的青年和禅师喝茶的故事),你学习一样的新的语言时需要把之前你擅长的语言的知识忘掉,就像一个已注满水的杯子,你只有把水倒掉才能重新装水,清掉以前的知识(看法),你才能更好的接受新的知识(或者不容易授已有知识体系的限制)。
但其实人们在学习一种自己不知道的知识点时,会更需要一些合理的类比,将新的知识的相同和不同和已有的概念进行类比,这样一个人可以更快的了解新的概念。我觉得我很难把已注满水的杯子倒空,那我就先倒半杯吧。所以我之后的文章还是会有一些和Java类比的地方。
变量声明
JavaScript使用var关键字进行变量的声明,而且这个变量是没有类型的,像Java这种变量具有数据类型的语言被称为静态数据类型语言,JavaScritp自然就可称为动态数据类型语言了。如:
var foo;
因为没有变量类型,所以对于同一个变量,既可以赋值为字符串,也可以赋值为数字。虽然说这并不是一个好习惯,在实际工作中也应该避免出现这样的代码。
var foo;
foo = "abs";
foo = 123;
和Java不同的还有,在声明变量时,可以不需要关键字var,这样的变量称为隐式声明变量。采用隐式声明的变量都是全局变量,即使在函数内部隐式声明的变量也属于全局变量,这点要注意。相对于隐式声明,在函数外部通过var声明的变量也是全局变量。一般不推荐使用隐式声明合局变量,而且在strict模式下,隐式声明全局变量会报错。
strict mode: ES5中引入“严格模式”,同正常模式相比,严格模式有很多行为上的不同。其中一个不同的行为就是严格模式禁止自动或隐式地创建全局变量。
常量声明使用const。
ES6添加了一个新的关键词:let。let与var一样,也可以用来声明变量,但它有着更好的作用域规则,let声明的变量拥有块级作用域。其实let这一点就和我们在Java的方法或者{}块级作用域中声明的变量一样。
基本数据类型
在JavaScript中,有5种基本数据类型:
- 字符串(string)
- 数值(number)
- 布尔(Boolean)
- null
- undefined
这5种基本数据类型之外都被称为Object类型,可以使用内置的typeof函数判断变量的类型。被声明但未进行赋值的变量,其值为undefined。
** 字符串型**
和Java一样,JavaScript的字符串型也是不可变类型,所以字符串值是不能改变的。使用“+”连接两个字符串变量会生成一个新的字符串值。不过在JavaScript中,字符串型是一种内建类型,还存在一种字符串类(String,注意首字母大写),相当于是string类型的包装类,如Java中的int和Integer类的关系一样。
字符串型可以使用两种引号(单引号和双引号)来包围字符串字面量,这有一个好处就是可以通过两种引号的灵活运用以减少转义字符(\)的使用。
var hello = 'I say "yes"';
console.log(log);
还记得第一篇文章准备的运行环境吗?大家可以把这后出现的代码都在哪个环境下自己手写运行一下,这个非常有必要!使用Chrome查看运行结果的话,修改了代码再刷新一下浏览器即可。
输出:
I say "yes"
字符串型(基本类型)和String类之间也同样支持隐式类型转换。
var s = '012';
console.log(s.length);
字符串对象可以使用new运算符显式的生成:
var str = new String('abc');
字符串类型的比较
JavaScript有种相等的比较运算符:“==”和“===”,与之对应的判断不相等的运算符为“!=”和“!==”。区别在于,“===”在比较时不会对数据类型进行转换,称为严格相等。如果我们只考虑字符串之间的比较,那么“==”和“===”的结果是没有区别的。
var s1 = '012';
var s2 = '0';
var s3 = s2 + '12';
console.log(s1 == s3);
console.log(s1 === s3);
正如前面提到的,字符串型和字符串类是两种类型,字符串型是基本类型,而字符串类属于对象(Object)类型。所以在判断两者相等上是有差异的。
var s1 = new String('abc');
var s2 = new String('abc');
console.log(s1 == s2);
console.log(s1 === s2);
两个结果都是“false”。所以想要比较两个字符串对象的内容是否相等,需要进行一下类型转换:
console.log(s1 + '' == s2);
"=="会进行隐式类型转换,所以上面的s2对象也会被转换成字符串型。对比结果为“true”。
** 数值型 **
在JavaScript中,数值的内部结构为64位的浮点小数。所以整数和浮点数在JavaScript的内部是一样的,不存在类型转换问题,对0做除法也不会得到错误的结果。
对于浮点数来说,基本上并不能正确表达一个数的值,大部份情况下只是表达一个近似值而已。
console.log(0.1 + 0.2);
console.log((0.1 + 0.2) == 0.3);
0.1 + 0.2得到的值是:0.30000000000000004。
正如存在字符串类(String类),JavaScript中也存在数值类(Number类)。
** NaN **
对NaN进行任何运算,其结果都是NaN。NaN的运算还具有更为特别的性质,NaN不但不与其他任何数值相等,就算是两个NaN的值也是不相等的。也就是说我们不能用“==”来判断一个值是否为NaN,在JavaScript中有一个全局函数isNaN,用来判断值是否为NaN。
** 布尔型 **
这个可以省略先,用你知道的Java的相关布尔型的知识已足够。
** null型 **
null值的含义为没有引用任何对象,对null值进行typeof运算得到的结果是“object”。因此,其他类型的数据都可以通过typeof运算来进行类型判断,但对于null型来说,就必须通过和null值的等值判断才能确定。
console.log(typeof null);
null没有与之相对应的Null类,所以“null.toString()”这样的代码是会产生TypeError异常:
test.html:14 Uncaught TypeError: Cannot read property 'toString' of null
** undefined型 **
从字面意思来看,undefined值似乎和null值是一样的,但实际上,undefined并非字面量,而是一个预定义的全局变量。
undefined = 'abc';
console.log(undefined);
也就是说我们给undefined重新赋值并不会报错,只是因为在ES5版中undefined变为了只读变量,所以我们赋值没有什么效果,上面的输出还是“undfined”。
与null的值区别:null值指的是没有引用任何对象,而undefined指的是一个尚未定义的值。要使一个变量的值为null,必须将null以字面量的形式赋值给访变量。
var s;
console.log(typeof s);
除了基本类型之外,其他的所有类型都是Object类型,不过JavaScript还有一种函数(Function)的类型,可以将其理解为Object类型里的一种特别类型,或者简单说函数也是一种对象。这也是JavaScript和Java中的函数最大的不同。
function f() {}
console.log(typeof f);
结果会显示“function”。
最后
好像已经够长的了,再写很多人就要打瞌睡了,只能:未完待续......