JavaScript基础部分
JavaScript基础部分
阅读课本:JavaScript高级程序设计(第3版)
基本概念:
一、语法:
(1)变量名区分大小写; 例如变量名test和变量名Test分别表示两个不同的变量;
关键字不能当函数名:例如typeof; 这样写是不对的。
注意:不能把关键字、保留字、true、false和null用作标识符。
(2)标识符:变量、函数、属性的名字,或者函数的参数;
标识符的命名规则:
(a)第一个字符必须是一个字母、或是下划线(_)或是一个美元符号($);
(b)其他字符可以是字母、下划线、美元符号或数字;
(c)采用驼峰大小写格式:第一个字母小写,剩下的每个单词的首字母大写;
例如:firstSecond;myCar;doSomeThingImportan;(最佳的命名实践)
(3)注释:分为单行注释和多行(块级)注释。
(a)//单行注释
(b)多行注释是以/*开头,*/结尾。
/*
* 这是一个多行
* (块级)注释
*/
注意:多行注释的第二和第三行都以一个星号开头,但这不是必需的,之所以添加那两个星号,纯粹是为了提高注释的可读性。
(4)严格模式;ECMAScript 5引入了严格模式(strict mode)的概念;
它定义了一种不同的解析与执行模式;与之前的ECMAScript3相比,一些不确定的行为得到处理,而且对某些不安全的操作也会抛出错误。
启用严格模式:需要用以下语句。
"use strict";
对于代码而言,其实它是一个编译指示(pragma);用于告诉支持的JavaScript引擎切换到严格模式。
具体的操作方法如下:
function doSometing(){
"use strict";
//函数体
}
(5)语句
(1)ECMAScript中的语句以一个分号结尾;如果省略分号,则由解析器确定语句的结尾,不推荐;
如下例所示:
var sum = a + b //即使没有分号也是有效的语句——不推荐
var diff = a - b; //有效的语句——推荐
小结:加上不是必需,却不能省略的分号,可以避免很多错误的同时,在某些情况下增进代码的性能。
(2)代码块把多条语句组合在一起,以{}的形式。
if (test){
test = false;
alert(test);
}
虽然条件控制语句(如if语句)只在执行多条语句的情况下才要求使用代码块,但最佳实践是始终在控制语句中使用代码块——即使代码块中只有一条语句,例如:
if (test)
alert(test); //有效但容易出错,不要使用
------------------------------------------------
if (test){
alert(test); //推荐使用
}
小结:使用代码块,让编码意图更加清晰,也能降低修改代码时出错的几率。
二、关键字和保留字
关键字:具有特定的用途,可用于表示控制语句的开始或结束,或者用于执行特定的操作等。
关键字、保留字也是语言的保留的,不能用作标识符。
三、变量
ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。
每个变量仅仅是一个用于保存值的占位符而已。
定义变量时要使用var(关键字)操作符,后跟变量名(即一个标识符)。
var message;
解析:定义了一个名为message的变量,该变量可以用来保存任何值;
如果未初始化的变量,会保存一个特殊的值——undefined;
ECMAScript也支持直接初始化变量,定义变量的同时直接赋值。
var message = "hi";
①局部变量
使用var定义的变量将成为定义该变量的作用域中的局部变量。例如:
function test(){
var message = "hi"; // 局部变量
}
test();
alert(message); //错误!
如果直接运行代码会报错:Uncaught ReferenceError: message is not defined.
②全局变量
省略var操作符,因而message就成了全局变量。
function test(){
message = "hi"; // 全局变量(不推荐)
}
test();
alert(message);
小结:这个例子省略了var操作符,因而message就成了全局变量。
只要调用一次test()函数,这个变量就有了定义,就可以在函数外部的任何地方都被访问到。
在局部作用域中定义的全局变量很难维护,而且如果有意地忽略了var操作符,也会由于在局部作用域中相应变量不会马上被调用而导致不必要的混乱。
在严格模式下,给未经声明的变量赋值,会导致抛出ReferenceError错误。
一条语句定义多个变量:(建议换行和缩进,提高代码的可读性)
var message = "hi",
found = "false",
age = 29;
四、数据类型
ECMAScript中有5种简单数据类型(也称为基本数据类型):
Undefined、Null、Boolean、Number和String。
还有1种复杂数据类型——Object。
Object本质上是由一组无序的名值对组成的。
typeof操作符
typeof是一个操作符,不是一个函数。
鉴于ECMAScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型----typeof。
使用typeof操作符可能返回下列某个字符串。
"undefined"——如果这个值未定义;
"boolean"——如果这个值是布尔值;
"string"——如果这个值是字符串;
"number"——如果这个值是数值;
"object"——如果这个值是对象或null;
"function"——如果这个值是函数。
下面是几个使用typeof的例子;
var message = "some string";
alert(typeof message); //string
alert(typeof(message)); //string
alert(typeof 95); //number
alert(typeof null); //object
<script type="text/javascript">
function sum(){
console.log(1+1);
}
sum();
alert(typeof sum); //function
</script>
注意:从技术角度讲,函数在ECMAScript中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,因此通过typeof操作符来区分函数和其他对象是有必要的。
Undefined类型
Undefined类型只有一个值,即特殊的undefined。
使用var声明变量,但未对其加以初始化时,这个变量的值就是undefined。例如:
var message;
alert(message == undefined); //true
这个例子与下面的例子是等价的:
var message = undefined; //不推荐(显示初始化)
alert(message == undefined); //true
Null类型
Null类型只有一个值的数据类型,即特殊的值是null。
从逻辑角度来看,null值表示一个空对象指针。
var car = null;
alert(typeof car); //object
实际上,undefined的值是派生自null值的。
alert(null == undefined); //true
Boolean类型
Boolean类型是使用得最多的一种类型,两个值:true和false。例子如下:
var found = true;
var lost = false;
注意:Boolean类型的字面值true和false是区分大小写的。
也就是说,True和False(以及其他的混合大小写形式)都不是Boolean值,只是标识符。
ECMAScript中所有类型的值都有与这两个Boolean值等价的值。
要将一个值转换为其对应的Boolean值,可以调用转形函数Boolean(),如下所示:
var message = "Hello World!";
var messageAsBoolean = Boolean(message);
console.log(messageAsBoolean); //true
小结:字符串message被转换成了一个Boolean值。可以对任何数据类型的值调用Boolean()函数,而且总会返回一个Boolean值。
至于返回的这个值是true还是false,取决于要转换值的数据类型及其实际值。
n/a(或N/A),是not applicable的缩写,意思是“不适用”。
var message = "Hello World!";
if (message){
alert("Value is true"); //弹出"Value is true";
}
因为字符串message被自动转换成了对应的Boolean值(true)。
Number类型
Number类型:可以表示整数和浮点数值;
(1)整数;
var intNum =55;
(2)浮点数值;
var floatNum1 = 1.1;
var floatNum2 = 0.1;
var floatNum3= .1; //有效,但不推荐
由于保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会不失时机地将浮点数值转换为整数值。
var floatNum1 = 1.; //小数点后面没有数字----解析为1
var floatNum2 = 10.0; //整数---解析为10
var floatNum = 3.125e7; //31250000
浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数。
var a = 0.1;
var b = 0.2;
alert(a+b); //0.30000000000000004;
我们来看一下,关于浮点精度的例子。
var a = 0.1;
var b = 0.2;
//alert(a+b); //0.30000000000000004;
if (a + b == 0.3){ //精度误差会导致无法测试特定的浮点数值。
alert("You got 0.3.");
}
我们改一下代码,如下所示:
var a = 0.25;
var b = 0.05;
//alert(a+b); //0.3;
if (a + b == 0.3){ //通过
alert("You got 0.3.");
}
注意:永远不要测试某个特定的浮点数值,因为浮点数值计算会产生舍入误差的问题,这是使用基于IEEE754数值的浮点计算的通病。
(3)数据范围
ECMAScript能够表示:
最小的数值保存在Number.MIN_VALUE(结果是:5e-324);
最大的数值保存在Number.MAX_VALUE(结果是:1.7976931348623157e+308);
如果某次计算的结果得到了一个超出JavaScript数值范围的值,那么这个数值将被自动转换成特殊的Infinity值。
Infinity分正无穷(Infinity)和负无穷(-Infinity)。
无穷大其涵义是绝对值趋向于无穷大,也就是说“无穷大”本身可能是正无穷大,也可能是负无穷大;
Infinity是不能参与计算的数值。
isFinite()函数:检测一个数值是不是位于最小和最大的数值之间。位于之间,即返回true。
例如:
var result = Number.MAX_VALUE + Number.MAX_VALUE;
//alert(result); 结果为:Infinity;
alert(isFinite(result)); //false
alert(Number.NEGATIVE_INFINITY); //-Infinity
alert(Number.POSITIVE_INFINITY); //Infinity
(4)NaN
NaN,即非数值(Not a Number)是一个特殊的数值。
用于表示一个本来要返回数值的操作数未返回数据的情况(这样就不会抛出错误了)。
在ECMAScript中,任何数值除以0会返回NaN。
alert(5/0); //indifiny正无穷。
alert(-5/0); //-indifiny负无穷。
实际上只有0除以0才会返回NaN,正数除以0返回Infinity,负数除以0返回Infinity。
任何涉及NaN的操作(例如NaN/10)都会返回NaN。
NaN与任何值都不相等,包括NaN本身。
alert(NaN == NaN); //false
isNaN():确定这个参数是否“不是数值”;不是数值:true; 是数值:false;
在接收到一个值之后,会尝试将这个值转换为数值。
任何不能被转换为数值的值都会导致这个函数返回true。
console.log(isNaN(NaN)); //true
console.log(isNaN(10)); //false(10是一个数值)
console.log(isNaN("10")); //false(可以被转换成数值10)
console.log(isNaN("blue")); //true(不可以被转换成数值)
console.log(isNaN(true)); //false(可以被转换成数值1)
console.log(isNaN(false)); //false(可以被转换成数值0)
(5)数值转换函数
Number()、ParseInt()和parseFloat()都可以把非数值转换为数值。
Number():用于任何数据类型。
ParseInt()和parseFloat:专门用于把字符串转换成数值。
Number()函数的转换规则如下:
①如果是Boolean值,true和false将分别被转换为1和0。
console.log(Number(true)); //1
console.log(Number(false)); //0
②如果是数字值,只是简单的传入和返回。
console.log(Number(1)); //1
console.log(Number(0)); //0
③如果是null值,则返回0;
var car = null;
console.log(Number(car)); //0
④如果是undefined,返回NaN;
var message;
console.log(Number(message)); //NaN
如果是字符串,遵循下列规则:
(a)如果字符串只包含数字,则将其转换为十进制数值。
<script type="text/javascript">
var a = 1;
var b= -10;
var c= 123;
var d = "123";
var e = "011";
console.log(Number(a)); //1
console.log(Number(b)); //-10
console.log(Number(c)); //123
console.log(Number(d)); //123
console.log(Number(e)); //11 前导的零被忽略
</script>
(b)如果字符串包含有效的浮点格式,如“1.1”,则将其转换为对应的浮点数值。
<script type="text/javascript">
var a = 1.1;
var b= -1.1;
var c= "01.23";
console.log(Number(a)); //1.1
console.log(Number(b)); //-1.1
console.log(Number(c)); //1.23 前导的零被忽略
</script>
(c)字符串十六进制等转换成相同大小的十进制。
<script type="text/javascript">
var a = "0x1315";
console.log(Number(a)); //4885 十六进制转换成十进制
</script>
(d)如果字符串是空的(不包含任何字符),则将其转换为0;
<script type="text/javascript">
var a = "";
console.log(Number(a)); //0
</script>
(e)如果字符串包含其他的字符串,有可能被转换为NaN。
<script type="text/javascript">
var a = "Hello World!";
console.log(Number(a)); //NaN
</script>
ParseInt():处理整数的时候更常用。
①更多的是看其是否符合数值模式;
②忽略字符串前面的空格,直至找到第一个非空格字符;
<script type="text/javascript">
var a = " 123";
console.log(parseInt(a)); //123
</script>
③如果第一个字符不是数字字符或者负号,就会返回NaN;
<script type="text/javascript">
var a = " a123";
var b = -5;
var c = "5c";
console.log(parseInt(a)); //NaN
console.log(parseInt(b)); //-5
console.log(parseInt(c)); //5
</script>
④转换空字符串会返回NaN。
<script type="text/javascript">
a = "";
console.log(parseInt(a)); //NaN
</script>
⑤如果第一个字符是数字字符,会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符停止解析。
<script type="text/javascript">
a = "123a456";
b = "123a";
c = 22.15;
console.log(parseInt(a)); //123
console.log(parseInt(b)); //123
console.log(parseInt(c)); //22 小数点不是有效的数字字符
</script>
⑥能够识别出各种整数格式(即十进制、八进制、十六进制)。
<script type="text/javascript">
a = "0xA";
b = "070";
c = 85;
console.log(parseInt(a)); //10 0x开头十六进制,解析成十进制
console.log(parseInt(b)); //70 0开头是八进制,但是ECMAScript5引擎中,parseInt()已经不具备解析八进制的能力,因此前导的零会被认为无效,从而将这个值当成"70"; ECMAScript3引擎中,结果是56,具体解析八进制的解析能力。
console.log(parseInt(c)); //85
</script>
⑦parseInt()转换进制数时提供了第二个参数,即转换时使用的基数(即多少进制)。
var num = parseInt("0xAF", 16);
var numSec = parseInt("0xAF");
console.log(num); //175
console.log(numSec); //175
如果指定了16作为第二个参数,字符串可以不带前面的"0X",如下所示:
var num = parseInt("AF", 16);
var numSec = parseInt("AF");
console.log(num); //175
console.log(numSec); //NaN
下面,我们来看一下
var num1 = parseInt("10", 2); //2 (10)2 =(2)10
//2代表"10"是二进制,parseInt将其解析成十进制:1×2^1+0×2^0+=2+0=2
var num2 = parseInt("10", 8); //8 (10)8 =(8)10
//8代表"10"是八进制,parseInt将其解析成十进制:1×8^1+0×8^0=8+0=8
var num3 = parseInt("10", 10); //10
var num4 = parseInt("10", 16); //16 (10)16 = (16)10
//16代表"10"是十六进制,parseInt将其解析成十进制:1×16^1+0×16^0=16+0=16
console.log(num1);
console.log(num2);
console.log(num3);
console.log(num4);
ParseFloat():与parseInt()函数类似,从第一个字符(位置0)开始解析每个字符,直到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。
①字符串中的第一个小数点是有效的,第二个小数点就是无效的了。
如果字符串包含的是一个可解析为整数的数,(没有小数点或小数点后都是0),则返回整数。
var num1 = parseFloat("23.45");
var num2 = parseFloat("23.45.46");
var num3 = parseFloat("1234.00");
var num4 = parseFloat("1234.00blue");
var num5 = parseFloat("1234.001blue");
console.log(num1); //23.45
console.log(num2); //23.45
console.log(num3); //1234
console.log(num4); //1234
console.log(num5); //1234.001
②始终忽略前导的0,识别符点数值格式,也包括十进制整数格式。但十六进制格式的字符串则始终被转换成0。
var num1 = parseFloat("0xAF");
var num2 = parseFloat("037");
var num3 = parseFloat("37");
console.log(num1); //0
console.log(num2); //37
console.log(num3); //37
String类型
字符串:String类型用于表示由零或多个16位Unicode字符组成的字符序列。
字符串可以由双引号(")或单引号(')表示,如下所示:
var firstName = "Nicholas";
var lastName = "Zakas";
console.log(firstName); //Nicholas
console.log(lastName); //Zakas
小结:用单引号和双引号表示的字符串完全相同,使用的时候要前后保持统一。
var firstName = "Nicholas'; //语法错误(左右引号必须匹配)。
①字符字面量(转义序列)
用于表示非打印字符,或者具有其他用途字符。
(a)\n 换行
var firstName = "Hello\nWorld!";
console.log(firstName);
(b)\t 制表符
var firstName = "Hello\tWorld!";
console.log(firstName);
(c)\\ 反斜杠
var firstName = "Hello\tWorld!";
console.log(firstName);
(d)\' 单引号(')
var firstName = 'He said, \'hey.\'';
console.log(firstName);
(e)\" 单引号(")
var firstName = "He said, \"hey.\"";
console.log(firstName);
(f)\xnn 以十六进制代码nn表示的一个字符(其中n为0~F)。
var firstName = "\x41";
console.log(firstName); //A \x41 \x代表16进制 (41)16 = 4×16^1+1×16^0 = 64+1 = (65)10 十进制对应ACSII码为字符A。
(g)\unnnn 以十六进制代码nnnn表示的一个Unicode字符(其中n为0~F)。
console.log('\u03a3'); //Σ
(h)获得字符串的长度(length获得长度,字符串的数量,而不是unicode编码的数量。)
var text1 = "This is the letter sigma: \u03a3.";
var text2 = "Hello ";
console.log(text1.length); //28
console.log(text2.length); //8
②字符串的特点
(a)字符串是不可变的,不旦创建,它们的值就不能改变。
var lang = "Java";
(b)要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。
var lang = "Java";
lang = lang + "Script"; //第2行代码把lang值重新定义为"JavaScript";
实现这个操作的流程如下:
①创建一个能容纳10个字符的新字符串,填充字符串"Java"和"Script";
②销毁原来的字符串,"Java"和"Script",这两个字符串已经没有用了。
③转换为字符串
(a)toString()方法
数值、布尔值、对象和字符串都有toString()方法。
null和undefined的值没有这个方法。
var age = 11;
var ageAsString = age.toString();
console.log(ageAsString); //字符串"11"
console.log(typeof ageAsString); //string
var found = true;
var foundAsString = found.toString();
console.log(foundAsString); //字符串"true"
console.log(typeof foundAsString); //string
(b)调用数值的toString()方法时,可以传递一个参数(数值的基数)。
默认:以十进制格式返回数值的字符串表示。通过传递基数,可以表示“二进制”,“八进制”,“十六进制”等。
var num = 10;
document.write(num.toString()); //"10"
document.write(num.toString(2)); //"1010"
document.write(num.toString(8)); //"12"
document.write(num.toString(10)); //"10"
document.write(num.toString(16)); //"a"
(c)转型函数String()方法
针对null或undefined的情况下,使用转型函数String(),能够将任何类型的值转换为字符串。转换规则如下:
◇如果值有toString()方法,则调用该方法(没有参数),并返回相应的结果;
◇如果值是null,则返回"null";
◇如果值是undefined,则返回"undefined"。
举例如下:
var value1 = 10;
var value2 = true;
var value3 = null;
var value4;
document.write(String(value1)); //"10"
document.write(String(value2)); //"true"
document.write(String(value3)); //"null"
document.write(String(value4)); //"undefined"
Object类型
ECMAScript中的对象其实就是一组数据和功能的集合。
那如何创建一个对象呢?
var o = new Object(); //创建一个Object对象的实例对象并指向变量o。
var o = new Object; //有效,但不推荐省略圆括号。
小结:Object类型是所有它的实例的基础,所具有的属性和方法也同样存在于更具体的对象中。
Object的每个实例都具有下列属性和方法。
constructor:保存着用于创建当前对象的函数。
var o = new Object();----> Object()就是构造函数。
constructor:返回对创建此对象的数组函数的引用。
<script type="text/javascript">
var test = new Array();
if (test.constructor == Array){
document.write("This is an Array");
}
if (test.constructor == Boolean){
document.write("This is a Boolean");
}
</script>
看看具体如何使用object.constructor。
<script type="text/javascript">
function employee(name, job, age){
this.name = name;
this.job = job;
this.age = age;
}
var bill = new employee("Bill Gates", "Engneer", 1985);
console.log(bill.constructor == employee); //true
console.log(bill.constructor);
console.log(bill);
</script>