java与JavaScript基础部分学习对比
一、语法
1、区分大小写
- 在ECMAScript中,一切都区分大小写,包括变量、函数名、还是操作符;
- 在java中也同样严格区分大小写;
2、标识符
- 在声明规则上java和JavaScript是相同的,声明规则如下:
1、第一个字符必须是字母、下划线(_)或者美元符号;
2、剩下的其他字符可以是字母、下划线、美元符号或是数字; - 标识符的作用与在JavaScript中的对比:
1、在java和JavaScript中标识符是变量、函数、属性或函数参数的名称,但在js中函数名是指向函数的指针(它们跟其他包含对象指针的变量具有相同的行为—在方法对比章节中会详细解释)。
3、严格模式
-
在ECMA5的规范中,增加了严格模式的概念,严格模式是一种不同于JavaScript解析和执行的模型,在早先版本的ECMA版本中,一些不规范的写法在这种模式下将会被处理(抛出错误),而java中没有严格模式这个概念。
声明方式:“use strict” /* strict adj. 严格的,精确的*
可针对整个脚本开启严格模式,也可以只针对某个函数开启严格模式 <script> "use strict" </script> //fucntion 代表函数声明 function test(){ "use strict" //输出 console.log("Hello world") }
4、语句
- JavaScript和java中语句都以分号结尾,但是在JavaScript中,分号可以省略;
/注: 在JavaScript中,若是省略封号,那么意味着由解析器确定语句在哪里结尾,所以大多情况下推荐手动加分号,有助于提高性能,因为解析器会尝试着合适的位置上补上分号,以纠正语法错误/
5、关键字与保留字
1、在JavaScript和java中都有这个概念,关键字在开发过程中有特殊用途,如if、while、do 等流程控制语句,保留字只现在没有特定用途,但它们将来可能是关键字的词汇,以上所述,关键字与保留字皆不可用于标识符的声明;
6*:变量
6.1、JavaScript变量声明与细节:
声明方式: 操作符 变量名 = 值
var test1 = '';
let test2 = '';
const test3 = '';
/*var、const、let是声明变量的关键字也称之为操作符,var在所有ECMA版本中都可以使用,而const与let是ECMA新特性*/
1. 操作符:
例1: var message = “hellow”;
例2: let message2 = “hellow2”
例3:const message3 = “hellow3”
上述代码示例分别以操作符var、let、const定义了3个变量,可以用于保存任意类型的值(不初始化的情况下变量会保存一个特殊值undefined;)
/注: undefined是JavaScript数据类型的一种/
/注2: 变量的第一次赋值称为初始化/
1. 1 var、const、let的区别:
I、作用域不同:
var:使用var操作符定义的变量的作用范围只在该函数内,所以成为函数作用域(这里的作用域指的是外部函数访问变量的作用范围)
function test(){
var message = "hi"
}
console.log(message); //报错
let、const:使用 let和const声明的变量是块级作用域,并且在同一作用域内声明相同的变量名会报错;
/注: 块级作用域是ECMA6新特性,可以理解为在{}中书写的js代码/
/注2:let、const声明重复的变量名会报错,而用操作符var声明的变量不会/
II、变量提升:
var:使用var操作符定义的变量会自动提升到函数作用域的顶部,可以简单的理解为用var操作符声明的变量自动放在函数的第一行;
function test(){
console.log(name);
var name = "张三";
}
test(); //undefind
上述代码之所以不会报错是因为ECMA运行时把它看作如下代码:
function test(){
var name ;
console,log(name);
name = "张三";
}
let、const:let、const不会出现变量提升的情况
console.log(name);
var name = ‘张三’;
console.log(name);// ReferenceError没有定义
let name = “李四”;
原因:
在解析代码时,Javascript引擎也会注意到出现在块后面的let声明,只不过在此之前不能以任何方式引用未声明的变量。在let声明之前的执行该行代码的瞬间称为:”暂时性死区“;在此阶段引用任何后面才声明的变量都会报ReferenceError;
const与let、var的区别:
大体特性都与let相同,但const代表的是常量,使用该操作符声明的变量的值不可被改变(java中const也代表常量的声明);
/注:const不可被改变,指的是基本类型不可改变,而并非引用类型,详解请看6.3java与JavaScript变量的内存管理/
III、全局声明
使用var在全局作用域汇总声明的变量会成为window对象的属性,而使用let声明则不会;
6.2、Java变量声明:
声明方式:数据类型 变量名 = 值 ;
1. 数据类型见6.3Java与JavaScript数据类型的区别;
2. 变量名与值:
变量名即标识符,命名规则与标识符相同,值的方面分为数据类型与引用类型,它们在内存中的储存方式不同;
3. 强语言类型与若语言类型:
由上可知,java的变量声明方式为:
数据类型 变量名 = 值;
JavaScript的变量声明方式为:
操作符 变量名 = 值;
由上可知java的声明变量的方式必须指出具体的数据类型,如int、double、float而JavaScript是使用const、let、var来声明的无法具体声明数据类型;在这里可以简单理解为,强语言类型如java变量的声明方式——具体指出数据类型,而弱语言类型如JavaScript变量的声明方式——无法值出具体的数据类型。
6.3 Java与JavaScript数据类型的区别
JavaScript数据类型:
- ECMAScript有6种简单的数据类型(原始/基本数据类型):
Undefined、Null、Boolean、Number、String、Symbol; - ECMAScript的复杂数据类型:
Object(对象):是一种无序名值对的集合; - JavaScript数据类型介绍:
- Undefined:
Undefined类型只有一个值,那就是特殊值Undefined本身
当声明了变量但没有初始化时,就相当于给变量赋予了undefined值:
let message;
console.log(message == undefined); //true
在上述代码中可知,message变量并未赋值,但是却与undefined比较结果相同,上述示例等同于下
let message = undefined;
console.log(message == undefined ); // true
/* 注:一般来说,不用显式地给某个变量设置undefined的值,字面值undefined主要用于比较,而且在ECMA-262第三版前是不存在的,增加这个值的目的就是未来明确空对象指针(null)和未初始化变量的区别 */
/*注2:一个值为undefined的变量与未定义变量是有区别的,尽管使用typeOf判断数据类型的时候的结果都会显示undefined,但是console.log未定义的变量会报错
*/
/*注3:typeof 是一个js中的操作符,用于判断变量的数据类型,如 :
let message;
console.log(typeof message) //undefined
*/
- Null类型
Null类型同样只有一个值,即特殊值null,逻辑上讲,null对象表示一个空对象指针,在使用typeOf进行数据类型判断时,会返回Object
- 在定义将来要保存对象值的变量时,建议使用null来初始化,不要使用其他的值。这样,只要检查这个变量的值是不是null就可以知道这个变量是否在后来被重新赋予了一个对象的引用;
- undefined值是由null值派生而来的,因此ECMA-262将它们定义为表面上相等;
console.log( null == undefined ); // true
- 用等于操作符==比较null和undefined始终返回true,双等于号操作符会为了比较而转化它的操作数,转化为同一种类型比较;
- null和undefined的用途完全无关,前者永远不必显式地将变量值设置为undefined,但是null不一样,任何时候只有变量需要保存对象,而此刻有没有相应的对象时,就应该用null去填充该变量,这样可以保持null是空对象指针的语以,也程序维护时的检查;
- null是一个假值;
- Boolean类型
Boolean(布尔值)类型是ECMA中使用最频繁的类型之一,有两个字面值:true和false,这两个布尔值不等同于数值,因此true不等于1,false不等于0
- 布尔值字面量true和false区分大小写,因此True和False可以是有效标识符,但是不是布尔值;
- 虽然布尔值只有两个,但所有其他ECMA类型的值都有相应的布尔值等价形式;
- 代码示例如下:
let message = 'Hello World';
let messageAsBoolean = Boolean(message);
//message会被转换为布尔值并保存在变量messageAsBoolean中;
上述示例,Boolean()转型函数可以在任意数据类型上调用,并且返回一个布尔值
4.不同类型布尔值转换规则:
数据类型 | 转换为true | 转换为false |
---|---|---|
Boolean | ture | false |
String | 非空字符串 | 空字符串 |
Number | 非零数值与无穷数值 | 0 、NaN |
Object | 任意对象 | null |
Undefined | N/A (不存在) | Undefined |
- Number 类型
Number类型使用IEEE 754 格式表示整数和浮点值(在某些语言中也叫做双精度值)。不同的数值类型相应地也有不同的数值字面量格式。
- 整数:
let intNum = 55;//整数
最基本的数值字面量格式是十进制数,但整数也可以用八进制(以8为基数)或十六进制(以16为基数)字面量表示,对于八进制来说第一个数字必须是(0),然后是相应的数字(0~7);若是字面量中包含的数字超出了应有的范围,就会忽略前缀的0,后面的数字会继续按照10进制处理;同理,十六进制也一样,但是以0x开头,数值范围不可超过f,十六进制中的字母大小写均可;
let num1 = 070 // 八进制56
let num2 = 079 // 无效八进制,按照十进制处理,值为79
let num3 = 0xA // 十六进制10
let num4 = 0x1f // 十六进制31
- 浮点值
let float1 = 1.1;
let float2 = 0.1;
let float3 = .1; // 有效,但不推荐
如上代码所见,要定义浮点值,数值中必须包含小数点,而且小数后面必须至少有一个数字,虽然小数点前面不是必须有整数,如下图示,引擎会自动补0,但推荐加上,语义更通顺,并且可以避免性能的浪费;
细节 1. 因为存储浮点值使用的内存空间是存储整数值的两倍,所以ECMA总是想方设法把值转换为整数;在小数点后面没有数字的情况下,数值就会变成整数,同理,如果整数后面跟着.0那么它也会被转换为整数;
细节 2. 对于非常大或非常小的数值,浮点值可以用科学计数法来表示。科学计数法用于表示一个应该乘以10的给定次数的幂(次数可正可负);
let float = 3.125e7; => 31250000
细节 3. 浮点值的精确度最高可达17位小数,但在算术计算中远不如整数精确;
例如:
0.1 加 0.2 得到的不是0.3而是0.3000…0004;由于这种微小的舍入错误,导致很难测定特定的浮点值。
if( a + b == 0.3){
console.log("You got 0.3.");
}
如果上述代码的值是0.1和0.2,由于它们的值是0.3000…0004所以与0.3不相等,因而判断失败;
细节 4. 值的范围;
由于内存空间有限,ECMA并不支持表示这个世界上所有的数值。ECMA可表示最小值为Number.MIN_VALUE中,在浏览器中约为5e-324;最大值为Number.MAX_VALUE中;如果某个计算得到的数值结果超出了JS可以表示的范围,那么这个数值会被自动转换为一个特殊的Infinity(Infinity区分正负,正数代表无穷大,负数代表无穷小);
- NaN
NaN是Number数据类型的特殊值,意为”不是数值“(Not a Number),用于表示本来要返回数值的操作失败了;例如,0除任何数在其他语言中都会导致错误,从而中止代码执行,但在ECMA中,0,+0,-0相除都会返回NaN: - 数值转换
有3个函数可以将数值转化为非数值,如Number()、parseInt()、parseFloat();
Number转化规则:Number是转型函数可以用于任何数据类型,后两个函数主要用于将字符串转换为数值; parseInt()、parseFloat()主要用于将字符串转化为数值
数据类型 | 值 | 转化结果 |
---|---|---|
布尔值 | true/fasle | 1/0 |
数值 | all(所有) | 数值本身 |
Null | null | 0 |
Undefined | undefined | 0 |
字符串 | 包含数值字符 | 转换为十进制数 |
字符串 | 空字符串 | 0 |
字符串 | 非空字符串或包含字符 | NaN |
当对象调用ValueOf()方法,并按照上述规则转换返回值,如果转换的结果是NaN,则调用toString()方法,再按照转换字符串的规则进行转换。