这一片文章我们主要谈论javascript
的基本语法和数据类型,当然还是最基础的不过多赘述,希望刚入门的同学还是看一下为好,不是看到这个标题觉得不就是语法和数据类型么,就那么点知识,早就会了。
ECMA-262 描述了一组具有特定用途的关键字。这些关键字可用于表示控制语句的开始或结束,或者用于执行特定操作等。按照规则,关键字也是语言保留的,不能用作标识符
。以下就是ECMAScript的全部关键字(带*号上标的是第5 版新增的关键字):
break | do | instanceof | typeof |
---|---|---|---|
case | else | new | var |
catch | finally | return | void |
continue | for | switch | while |
debugger* | function | this | with |
default | if | throw | delete |
in | try |
ECMA-262 还描述了另外一组不能用作标识符的保留字。尽管保留字在这门语言中还没有任何特定的用途。但它们有可能在将来被用作关键字。以下是ECMA-262 第3 版定义的全部保留字:
abstract | enum | int | short |
---|---|---|---|
boolean | export | interface | static |
byte | extends | long | super |
char | final | native | synchronized |
class | float | package | throws |
const | goto | private | transient |
debugger | implements | protected | volatile |
double | import | public |
第5 版把在非严格模式下运行时的保留字缩减为下列这些:
class | enum | extends | super |
---|---|---|---|
const | export | import |
在严格模式下,第5 版还对以下保留字施加了限制:
implements | package | public | interface |
---|---|---|---|
private | static | let | protected |
yield |
注意, let 和yield 是第5 版新增的保留字;其他保留字都是第3 版定义的。为了最大程度地保证兼容性,建议大家将第3 版定义的保留字外加let 和yield 作为编程时的参考。
在实现ECMAScript 3 的JavaScript 引擎中使用关键字作标识符,会导致”Identifier Expected” 错误。而使用保留字作标识符可能会也可能不会导致相同的错误,具体取决于特定的引擎。
第5 版对使用关键字和保留字的规则进行了少许修改。关键字和保留字虽然仍然不能作为标识符使用,但现在可以用作对象的属性名。一般来说,最好都不要使用关键字和保留字作为标识符和属性名,以便与将来的ECMAScript 版本兼容。
除了上面列出的保留字和关键字,ECMA-262 第5 版对eval 和arguments 还施加了限制。在严格模式下,这两个名字也不能作为标识符或属性名,否则会抛出错误。
ECMAscript
中有五种简单数据类型
(也叫做基本的数据类型):Undefined
.Boolean
,String
,Null
,Number
.还有一种复杂的数据类型(有时候也叫引用数据类型)–Object,Object本质上是一组无序的键值对组成的。ECMAscript
不支持任何创建自定义类型的机制,而所有的值都是上述的六种数据类型之一。
这个操作符(这里说的不是函数,因为它不是一个函数)一般是在调试的时候使用,它的返回值有六个:undefined(值为定义)
,boolean(布尔值)
,string(字符串)
,number(数字)
,object(这个值是对象或者null)
,function(这个值是函数)
。
对应于正则表达式而言,他其实也是对象(RegExp类型的对象)的另一种形式,但是对于Chrome7和safari5之前的版本返回的是function
其他的浏览器返回的是object
下面我们来看一个简单的例子
var msg; //如果没有赋值,默认是undefined
typeof msg; //undefined
// age 没有定义
typeof age; //undefined
这个结果又逻辑上的合理性。因为虽然这两种变量从技术角度上看是有本质的区别的,但是实际上那种变量都是不可能执行真正的操作的。
即使未初始化的变量会自动被赋值为undefined
,但是显示的初始化变量仍然是明智的选择,如果能过做到这一点,那当typeof操作符返回的是undefined的时候,我们就能确定这个变量还没有被声明
console.log(undefined == null) // true
console.log(undefined === null) // false
实际上undefined
值是由null派生出来的,这是因为在ECMA-262
中规定他们的相等性要返回true
。
尽管null和undefined有这样的关系,但是他们的用途是完全不同的,在任何情况下都没有必要把一个变量的值设置为undefined但是同样夫人规则对应于null就是不合适的。以为只要意在保存对象变量还没有保存真正的变量的时候,就应该明确的让变量保存null。这样做不仅可以体现null作为空指针的惯例,而且能进一步的区分null和undefined
Number类型应该是ECMAscript中最令人关注的数据类型了,这种类型是使用的IEEE754
来表示整数和浮点数值
var num1 = 070; //表示八进制数
var num2 = 079 //无效的八进制数 表示79
var num3 = 0x1f //十六进制数
八进制的字面量在严格模式下是无效的,会导致javascript引擎报错
var f1 = 0.1;
var f2 = .1; //虽然是有效的0.1但是不推荐
var f3 = 1.0; //会自动转换为1
对于有些极大的或者极小的数值也可以用科学计数法表示,
var f4 = 3.125e7; //31250000
在这里还是要提示一下众所周知的浮点数不能比较相等法则,
在javascript中浮点数的最高精度是17位的小数,但在进行算术计算的时候精确度远远不如整数,例如0.1+0.2不等于0.3而是等于0.0000000000000004(4e-17)
这是使用基于IEEE754数据浮点计算的通病
由于内存的限制,ECMAscript并不能保存世界上所有的数,能保存的数能在浏览器中显示出来(通过Number.MAX_VALUE),最小值是(Number.MIN_VALUE)
当超出这个范围的时候,大于就变为Infinity,小于就变为-Infinity
var big = Number.MAX_VALUE + Number.MAX_VALUE;
console.log(big); //Infinity
可以使用isFinite()
函数判断这个值是否在最大值和最小值之间,如果在就返回true
通过访问Number.NEGATIVE_INFINITY
和Number.POSITIVE_INFINITY
来得到-Infinity
和Infinity
NaN,非数值类型(Not a Number)是一个特殊的值,这个数值表示一个应该返回数值的情况结果没有返回数值,在ECMAscript中,任何数值除以0并不会导致错误,会返回一个NaN,因此并不会影响代码的运行。
Nan本身有两个特点:任何设置NaN的操作都会返回NaN,这个特点在多步计算的时候可能导致错误,其次Nan和任何数值都不想等,包括本身:
console.log(NaN == Infinity)
console.log(NaN == 1)
console.log(NaN == NaN)
console.log(NaN == 1/0)
//以上结果返回的都是false
//下面是判断数据类型
isNaN(NaN) //true
isNaN('123') //false,进行了数据类型的转换
isNaN('f5') //true
isNaN(4) //false
运用isNaN()函数可以判断这个变量是否是NaN类型的。
最神奇的是isNaN也是支持对象操作的,在基于对象调用isNaN函数时,会首先调用对象的valueOf方法,然后确定该方法返回的值是否可以转换为数值,如果不能就基于这个返回值再调用toString()方法,在测试返回值
对应于string类型,讨论的会比较少一点,string类型用于友零或者多个16位的Unicode字符组成的字符序列,即字符串。js中的单引号和双引号是没有区别的(想对于PHP来讲)。
转义的只是在这里就不多说了,
字面量在这里只说一点:
var text = "this is \u30a3"
这个的长度是9因为\u30a3
转义后表示一个字符
字符串在我们平常的开发当中我们是一直在用的,但是很少人知道其中的原理,下面我们就来讨论一下字符串的特点。
ECMAscript中的字符串是不可变的,也就是说,字符串一旦被创建,他们的值就不能被改变。要改变某个变量保存的字符串就先要销毁原来的字符串,然后用一个新的值来填充该变量,例如下面的代码:
var lang = 'java';
lang = lang + 'script';
以上的代码是变量lang中包含字符串‘java’。而第二行代码把lang
的值重新定义为‘java’与’script’的结合,实际上这个操作过程如下:
1. 首先创建一个能容纳10个字符的新字符串
2. 然后将这个字符串中填充’java’和’script’
3. 最后一步是销毁原来的’java’字符串和’script’字符串,因为这两个字符串已经没用了
在这里主要注意的是null
和undefined
是没有toString()方法的,如果想要把他们转换为字符串可以使用转型函数String()
,能把任何类型的值转换为字符串var val = null;String(val)
当使用数值转换为字符串的时候,可以在toString()传递一个参数,表示把数值变为多少进制的字符串:var num = 10;num.toString(2)
返回的是1010;
ECMAscript
中对象其实就是一组数据
和功能
的集合。
三种实例化一个对象的方法:
var o = new Ocject();
var o = new Object;//不推荐使用
var o = {};//当今最常用的
object中的对象和属性在后面我们在去讨论
这个我们在这里说的具体一点
1. 加法运算
console.log(1+2)
var a ="121",
b =56,
c ="ss";
console.log(a+b);//12156
console.log(a+c);//121ss
//字符串转换我数值
var a = "21212";
+a //21212
var b = "ss";
+a //NaN
var c= "0xff";
+a //255
//数值转换为字符串
var a =45;
+a; //"45"
//布尔值的转换
+true //1
+fasle //0
减号的作用一般是都是用在正规的操作(也就是类型相同)的操作中,信息量虽然不是很大,但是还是有很多需要注意的地方,下面来举几个例子
var a = 5-true; //4 ,true被转换了
var b = NaN -1;//NaN
var c= 5-2 //3
var d = 5-"2";//3 “2”被转换为2
var e = 5-null; //5 null被转换为了0
在我们编程的时候,当使用比较的时候我们希望,有的时候类型不同可以数值一样就可以就好像(2和"2"
)是可以相等的,但是有时候我们希望要求数值和类型都是一样的才返回真。这就很矛盾了,在ECMAscript中的解决方案是提供两组操作数:相等和全等
相等
:先转换在比较
列出一下比较特殊的比较结果
表达式 | 值 |
---|---|
null == undefined | true |
“NaN” == NaN | false |
NaN == NaN | false |
NaN != NaN | true |
true == 2 | false |
undefined == 0 | false |
null == 0 | false |
全等
:仅比较不转换
全等就比较严格了,在这里就不讨论什么了。
注意:null == undefined会返回true,但是null === undefined会返回false,这是由于他们的类型不一样
函数对于任何语言来说都是一个核心的概念。
在这里主要说一个问题,细节会在后面继续讨论
我们都是知道在函数中的arguments
表示所有传进来的参数,比如说
function foo(a,b,c){
console.log(arguments[2] === c);//true
}
这个原因并不因为他们指向的是同一块内存,因为他们内存空间的值会相互同步,
arguments的值是不能被改写的如果改写的会操作