JavaScript - 基本概念

1. 语法

1.1 区分大小写

ECMAScript中的一切(变量、函数名和操作符)都区分大小写。


1.2 标识符

标识符: 指变量、函数、属性的名字,或者函数的参数。


标识符的格式规则:

  1. 第一个字符必须是一个字母、下划线(_)或一个美元符号($)
  2. 其他字符可以是字母、下划线、美元符号或数字
  3. 标识符中的字母也可以包含扩展的ASCII或Unicode字母字符(不推荐)
  4. 采用驼峰大小写格式,如myCarmyFirstClass
  5. 不能把关键字、保留字、true、false和null用作标识符

1.3 注释

  • 单行注释
// 这是单行注释
  • 多行注释
/*
 * 这是一个多行
 *(块级)注释
 */

上面注释中的第二和第三行都以一个星号开头,但这不是必需的。之所以添加那两个星号,纯粹是为了提高注释的可读性。


1.4 严格模式

ECMAScript5定义了一种不同的解析与执行模型。

在严格模式下,ECMAScript3中的一些不确定的行为将得到处理,而且对某些不安全的操作也会抛出错误。


要在整个脚本中启用严格模式,可以在顶部添加如下代码:

"use strict";

这是一个编译指示,用于告诉支持的JavaScript引擎切换到严格模式。


在函数内部的上方包含这条编译指示,也可以指定函数在严格模式下执行:

function doSomething() {
	"use strict";
	// 函数体
}

支持严格模式的浏览器包括IE10+、Firefox 4+、Safari5.1+、Opera 12+和Chrome。


1.5 语句

  • ECMAScript中的语句以一个分号结尾。
  • 如果省略分号,则由解析器确定语句的结尾。
    <script>
        // 有效,推荐
        var sum = a + b;

        // 有效,但不推荐
        var diff = a - b
    </script>

推荐加分号:

  1. 避免很多错误(例如不完整的输入)
  2. 可以放心删除多余的空格来压缩ECMAScript代码(代码行结尾处没有分号会导致压缩错误)
  3. 解析器不必花时间推测应该在哪里插入分号,会在某些情况下增进代码的性能

2. 关键字和保留字

  • 关键字:用于表示控制语句的开始或结束,或者用于执行特定操作等
    在这里插入图片描述
  • 保留字:还没有任何特定的用途,但它们有可能在将来被用作关键字

3. 变量

ECMAScript的变量是松散类型的,可以用来保存任何类型的数据。即每个变量仅仅是一个用于保存值的占位符而已。

定义一个变量:

var message;

// 未经过初始化的变量,会保存一个特殊的值——undefined
console.log(message);  // undefined

变量可以用来保存任何值:

var message = 'hello';

修改变量值(可以在修改变量值的同时修改值的类型):

var message = 'hello';
message = 123;

上述代码将字符串值修改成为数字值。


该操作有效,但不建不建议修改变量所保存值的类型。


如果在函数中使用var定义一个变量,那么这个变量在函数退出后就会被销毁:

function test() {
	var message = 'hrllo'; // 局部变量
}
test();
console.log(message); // 错误

省略var操作符,可以创建一个全局变量:

function test() {
	message = 'hrllo'; // 全局变量
}
test();
console.log(message); // hello

虽然省略var操作符可以定义全局变量,但不推荐。

  1. 在局部作用域中定义的全局变量很难维护
  2. 如果有意地忽略了var操作符,也会由于相应变量不会马上就有定义而导致不必要的混乱
  3. 给未经声明的变量赋值在严格模式下会导致抛出ReferenceError错误

一条语句定义多个变量,把每个变量(初始化或不初始化均可)用逗号分隔开:

var message = 'hello',
	bool = true,
	num = 123;

4. 数据类型

  • 基本数据类型:Undefined、Null、Boolean、Number和String
  • 复杂数据类型:Object(Object本质上是由一组无序的名值对组成的)

ECMAScript不支持任何创建自定义类型的机制,所有值最终都将是上述6种数据类型之一。

4.1 typeof 操作符

作用:检测给定变量的数据类型。


对一个值使用typeof操作符可能返回下列某个字符串

  • undefined:值未定义
  • boolean:布尔值
  • string:字符串
  • number:数值
  • object:对象或null
  • function:函数

var message = 'hello';
alert(typeof message); // "string"
alert(typeof (message)); // "string"
alert(typeof 123); // "number"

// 特殊值null被认为是一个空的对象引用
alert(typeof null); // "object"

4.2 Undefined 类型

Undefined类型只有一个值,即特殊的undefined。

在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined。

var message;
alert(message == undefined); // true

4.3 Null 类型

Null类型只有一个值,这个特殊的值是null。

从逻辑角度来看,null值表示一个空对象指针,因此使用typeof操作符检测null值时会返回 “object”。

如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null。


4.4 Boolean类型

Bool类型只有两个字面值:true和false。


注意:

  1. 这两个值与数字值不是一回事,因此true不一定等于1,而false也不一定等于0
  2. Boolean类型的字面值true和false是区分大小写

将一个值转换为其对应的Boolean值,可以调用转型函数Boolean():

数据类型转换为true的值转换为false的值
Booleantruefalse
String任何非空字符串“”(空字符串)
Number任何非0数字值(包括无穷大)0和NaN
Object任何对象null
UndefinedN/Aundefined

4.5 Number 类型

  • 十进制:
var num = 10;
  • 八进制:
    1. 八进制字面值的第一位必须是零(0),然后是八进制数字序列(0~7)
    2. 如果字面值中的数值超出了范围,那么前导零将被忽略,后面的数值将被当作十进制数值解析
var num1 = 070; // 八进制的56
var num2 = 079; // 79
var num3 = 08; // 8

八进制字面量在严格模式下是无效的,会导致支持该模式的JavaScript引擎抛出错误。

  • 十六进制:
    1. 字面值的前两位必须是0x,后跟任何十六进制数字(09及AF)
    2. 字母A~F可以大写,也可以小写
var num1 = 0xA; // 十六进制的10
var num2 = 0x1f; // 十六进制的31

注意:

  1. 在进行算术计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值。
  2. 鉴于JavaScript中保存数值的方式,可以保存正零(+0)和负零(-0),且 +0 等于 -0。

1)浮点数值

数值中必须包含一个小数点,并且小数点后面必须至少有一位数字。

var floatNum1 = 1.1;
var floatNum2 = 0.1;
var floatNum3 = .1; // 有效,但不推荐

注意:

  • 保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会不失时机地将浮点数值转换为整数值。
    • 如果小数点后面没有跟任何数字,那么这个数值就可以作为整数值来保存。
    • 如果浮点数值本身表示的就是一个整数(如1.0),那么该值也会被转换为整数。

  • 对于那些极大或极小的数值,可以用e表示法(即科学计数法)表示的浮点数值表示。
    • 在默认情况下,ECMASctipt会将那些小数点后面带有6个零以上的浮点数值转换为以e表示法表示的数值
var floatNum1 = 3.125e7; // 等于31250000
var floatNum2 = 3e-17; // 等于0.00000000000000003

  • 浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数。
    • 如,0.1加0.2的结果不是0.3,而是0.30000000000000004。所以不要测试某个特定的浮点数值。
alert( (0.1 + 0.2) == 0.3); // false

2)数值范围
  • 最小数值保存在Number.MIN_VALUE中——在大多数浏览器中,这个值是5e-324。
  • 最大数值保存在Number.MAX_VALUE中——在大多数浏览器中,这个值是1.7976931348623157e+308。
  • 超出JavaScript数值范围的值将被自动转换成特殊的Infinity值:
    • 如果这个数值是负数,则会被转换成-Infinity(负无穷)
    • 如果这个数值是正数,则会被转换成Infinity(正无穷)
    • Infinity值不能参与计算

3)NaN

NaN,即非数值(Not a Number),是一个特殊的数值,用于表示一个本来要返回数值的操作数未返回数值的情况。

特点:

  1. 任何涉及NaN的操作(例如在ECMAScript中,任何数值除以非数值会返回NaN,因此不会影响其他代码的执行)都会返回NaN
  2. NaN与任何值都不相等,包括NaN本身
alert(NaN == NaN); // false

针对NaN的这两个特点,ECMAScript定义了 isNaN() 函数。

  • isNaN()在接收到一个值之后,会尝试将这个值转换为数值。
  • 某些不是数值的值会直接转换为数值,例如字符串"10"或Boolean值。
  • 任何不能被转换为数值的值都会导致这个函数返回true。

4)数值转换

非数值转换为数值:Number()parseInt()parseFloat()

  • Number():转型函数,可以用于任何数据类型
  • parseInt():专门用于把字符串转换成数值
  • parseFloat():专门用于把字符串转换成数值

Number()函数的转换规则:

数据类型转换规则
Boolean值true和false将分别被转换为1和0
Number值简单的传入和返回
null值返回0
undefined返回NaN
字符串只包含数字(包括前面带正号或负号的情况)–> 十进制数值(忽略前导零)
包含有效的浮点格式 --> 对应的浮点数值(忽略前导零)
包含有效的十六进制格式 --> 相同大小的十进制整数值
空的(不包含任何字符) --> 0
包含除上述格式之外的字符 --> NaN
对象调用对象的valueOf()方法,然后依照前面的规则转换返回的值
如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值

parseInt()函数的转换规则:

  1. 会忽略字符串前面的空格,直至找到第一个非空格字符
  2. 如果第一个字符不是数字字符或者负号,parseInt()就会返回NaN
  3. 用parseInt()转换空字符串会返回NaN(Number()对空字符返回0)
  4. 如果第一个字符是数字字符,parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符
  5. 如果字符串中的第一个字符是数字字符,parseInt()也能够识别出各种整数格式
    为了消除在使用parseInt()函数时可能导致的无法解析八进制值的能力的问题,可以为这个函数提供第二个参数:转换时使用的基数(即多少进制):
var num = parseInt("0xAF", 16);  // 175

// 如果指定了16作为第二个参数,字符串可以不带前面的"0x"
var num = parseInt("AF", 16);  // 175
var num = parseInt("AF");  // NaN

因此,为了避免错误的解析,建议无论在什么情况下都明确指定基数。


parseFloat()函数的转换规则:

  • 从第一个字符(位置0)开始解析每个字符。
  • 一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。
  • 字符串中的第一个小数点有效,而第二个小数点无效,因此它后面的字符串将被忽略
  • 始终都会忽略前导的零
  • 只解析十进制值,因此它没有用第二个参数指定基数的用法
  • 如果字符串包含的是一个可解析为整数的数(没有小数点,或者小数点后都是零), parseFloat()会返回整数
var num1 = parseFloat("123abc"); // 123
var num2 = parseFloat("0xA"); // 0
var num3 = parseFloat("22.5"); // 22.5
var num4 = parseFloat("22.34.5"); // 22.34
var num5 = parseFloat("0908.5"); // 908.5
var num6 = parseFloat("3.125e7"); // 31250000

总结:

  • 转整数用praseInt();
  • 转小数用praseFloat();
  • 转数字用Number(),但比前面两种方式严格。

4.6 String类型

用于表示由零或多个16位Unicode字符组成的字符序列,即字符串。

字符串可以由双引号(")或单引号(’)表示,用双引号表示的字符串和用单引号表示的字符串完全相同。


ECMAScript中的字符串是不可变的。 即字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。


转换为字符串

toString()转换规则:

  • 数值、布尔值、对象和字符串值都有toString()方法
  • null和undefined值没有toString()方法
  • 多数情况下,调用toString()方法不必传递参数
  • 在调用数值的toString()方法时,可以传递一个参数:输出数值的基数。通过传递基数,toString()可以输出以二进制、八进制、十六进制,乃至其他任意有效进制格式表示的字符串值。
var num = 10;
alert(num.toString()); // "10"
alert(num.toString(2)); // "1010"
alert(num.toString(8)); // "12"
alert(num.toString(10)); // 10"
alert(num.toString(16)); // "a"

String()转换规则:

在不知道要转换的值是不是null或undefined的情况下,可以使用转型函数String(),这个函数能够将任何类型的值转换为字符串。

  • 如果值有toString()方法,则调用该方法(没有参数)并返回相应的结果
  • 如果值是null,则返回"null"
  • 如果值是undefined,则返回"undefined"

4.7 Object类型

对象可以通过执行new操作符后跟要创建的对象类型的名称来创建:

var obj = new Object();

// 不传递参数的情况下,可以省略圆括号
var obj1 = new Object; // 有效,但不推荐

Object的每个实例都具有下列属性和方法:

属性和方法含义
constructor构造函数,保存着用于创建当前对象的函数
hasOwnProperty(propertyName)用于检查给定的属性在当前对象实例中。作为参数的属性名(propertyName)必须以字符串形式指定
isPrototypeOf(object)用于检查传入的对象是否是当前对象的原型
propertyIsEnumerable(propertyName)用于检查给定的属性是否能够使用for-in语句,参数的属性名必须以字符串形式指定
toLocaleString()返回对象的字符串表示,该字符串与执行环境的地区对应
toString()返回对象的字符串表示
valueOf()返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同

5. 操作符

5.1 一元操作符

只能操作一个值的操作符叫做一元操作符。

  • 递增和递减操作符
var age = 29;
++age;  // 30 相当于 age = age + 1;
age++;  // 30
var age = 29;
--age;  // 28 相当于 age = age - 1;
age--;  // 28

5.2 位操作符

位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。

对于有符号的整数,32位中的前31位用于表示整数的值。第32位用于表示数值的符号:0表示正数,1表示负数。这个表示符号的位叫做符号位,符号位的值决定了其他位数值的格式。

  • 正数以纯二进制格式存储。例如,数值18的二进制表示是00000000000000000000000000010010,或者更简洁的10010。
  • 负数以二进制补码形式存储。
    • 求这个数值绝对值的二进制码
    • 求二进制反码,即将0替换为1,将1替换为0
    • 得到的二进制反码加1

  • 按位非

按位非操作符由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码。

  • 按位与

按位与操作符由一个和号字符(&)表示,有两个操作符数。

按位与操作只在两个数值的对应位都是1时才返回1,任何一位是0,结果都是0。

  • 按位或

按位或操作符由一个竖线符号(|)表示,有两个操作数。

按位或操作在有一个位是1的情况下就返回1,而只有在两个位都是0的情况下才返回0。

  • 按位异或

按位异或操作符由一个插入符号(^)表示,有两个操作数。

按位异或与按位或的不同之处在于,这个操作在两个数值对应位上只有一个1时才返回1,如果对应的两位都是1或都是0,则返回0。

  • 左移

左移操作符由两个小于号(<<)表示,这个操作符会将数值的所有位向左移动指定的位数。

左移操作会以0来填充空位。

  • 有符号的右移

有符号的右移操作符由两个大于号(>>)表示,这个操作符会将数值向右移动,但保留符号位(即正负号标记)。

用符号位的值来填充所有空位。

  • 无符号右移

无符号右移操作符由3个大于号(>>>)表示,这个操作符会将数值的所有32位都向右移动。对正数来说,无符号右移的结果与有符号右移相同。

无符号右移是以0来填充空位。

5.3 布尔操作符

  • 逻辑非

逻辑非操作符由一个叹号(!)表示,可以应用于ECMAScript中的任何值。无论这个值是什么数据类型,这个操作符都会返回一个布尔值

alert(!false); // true
alert(!"blue"); // false
alert(!0); // true
alert(!12); // false
alert(!NaN); // true
alert(!""); // true
  • 逻辑与

逻辑与操作符由两个和号(&&)表示,有两个操作数。

在有一个操作数不是布尔值的情况下,逻辑与操作就不一定返回布尔值:

  • 如果第一个操作数是对象,则返回第二个操作数
  • 如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对象
  • 如果两个操作数都是对象,则返回第二个操作数
  • 如果第一个操作数是null,则返回null
  • 如果第一个操作数是NaN,则返回NaN
  • 如果第一个操作数是undefined,则返回undefined
  • 逻辑或

逻辑或操作符由两个竖线符号(||)表示,有两个操作数。

如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值。


5.4 相等操作符

  • 相等和不相等

相等操作符由两个等于号(==)表示,如果两个操作数相等,则返回true。

不相等操作符由叹号后跟等于号(!=)表示,如果两个操作数不相等,则返回true。

表达式
null == undefinedtrue
“NaN” == NaNfalse
12 == NaNfalse
NaN == NaNfalse
NaN != NaNtrue
false == 0true
true == 1true
true == 2false
undefined == 0false
null == 0false
“12” == 12true
  • 全等和不全等

全等操作符由3个等于号(===)表示,它只在两个操作数未经转换就相等的情况下返回true。

如:null == undefined会返回true,因为它们是类似的值;但null === undefined会返回false,因为它们是不同类型的值。

5.5 条件操作符

语法形式:
variable = boolean_expression ? true_value : false_value;


6. 语句

6.1 if语句

if (condition) {
	statement1
} else {
	statement2
}

6.2 do-while语句

do-while语句是一种后测试循环语句,即只有在循环体中的代码执行之后,才会测试出口条件。

do {
	statement
} while(expression);

在对条件表达式求值之前,循环体内的代码至少会被执行一次。

6.3 while语句

while(expression) {
	statement
}

6.4 for语句

for语句也是一种前测试循环语句,但它具有在执行循环之前初始化变量和定义循环后要执行的代码的能力。

for(initialization; expression; post-loop-expression) {
	statement
}

使用while循环做不到的,使用for循环同样也做不到。也就是说,for循环只是把与循环有关的代码集中在了一个位置。

在for循环的变量初始化表达式中,也可以不使用var关键字。该变量的初始化可以在外部执行。如:

var count = 10;
var i;
for(i = 0; i < count; i++) {
	alert(i);
}
alert(i); // 10

for语句中的初始化表达式、控制表达式和循环后表达式都是可选的。将这三个表达式全部省略,就会创建一个无限循环,如:

for(;;) {
	doSomething();
}

5.5 for-in 语句

for-in语句是一种精准的迭代语句,可以用来枚举对象的属性。

for(property in expression) {
	statement
}

例如;

for(var propName in window) {
	console.log(propName);
}

在这里插入图片描述

如果表示要迭代的对象的变量值为null或undefined, for-in语句会抛出错误。ECMAScript 5更正了这一行为;对这种情况不再抛出错误,而只是不执行循环体。为了保证最大限度的兼容性,建议在使用for-in循环之前,先检测确认该对象的值不是null或undefined。

5.6 label 语句

使用label语句可以在代码中添加标签,以便将来使用。

label: statement

例如:

start: for(var i = 0; i < count; i++) {
	alert(i);
}

这个例子中定义的start标签可以在将来由break或continue语句引用。加标签的语句一般都要与for语句等循环语句配合使用。

5.7 break 和 continue 语句

break和continue语句用于在循环中精确地控制代码的执行。

  • break语句会立即退出循环,强制继续执行循环后面的语句
  • continue语句虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行

5.8 with 语句

with语句的作用是将代码的作用域设置到一个特定的对象中。

with(expression) {
	statement
}

定义with语句的目的主要是为了简化多次编写同一个对象的工作。

由于大量使用with语句会导致性能下降,同时也会给调试代码造成困难,因此在开发大型应用程序时,不建议使用with语句。

5.9 switch语句

switch(expression) {
	case value: statement
	break;
	case value: statement
	break;
	case value: statement
	break;
	default: statement
}

通过为每个case后面都添加一个break语句,就可以避免同时执行多个case代码的情况。

7. 函数

通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。ECMAScript中的函数使用function关键字来声明,后跟一组参数以及函数体。

语法格式:

function functionNane(arg0, arg1, ..., argN) {
	statement
}

例如:

function sayHi(name, message) {
	alert('hello' + name + ',' + message);
}

函数可以通过其函数名来调用,后面还要加上一对圆括号和参数:

sayHi('张三', '123');

在这里插入图片描述
返回值:

        function getSum(num1, num2) {
            return num1 + num2;
        }
        alert(getSum(1, 2));        

在这里插入图片描述
函数会在执行完return语句之后停止并立即退出。因此,位于return语句之后的任何代码都永远不会执行。

        function getSum(num1, num2) {
            return num1 + num2;
            console.log('不会输出这句话');
        }
        console.log(getSum(1, 2));

在这里插入图片描述
return语句也可以不带有任何返回值。

在这种情况下,函数在停止执行后将返回undefined值。这种用法一般用在需要提前停止函数执行而又不需要返回值的情况下。

7.1 参数

ECMAScript函数不介意传递进来多少个参数,也不在乎传进来参数是什么数据类型。

  • 即便定义的函数只接收两个参数,在调用这个函数时也未必一定要传递两个参数。可以传递一个、三个甚至不传递参数。
  • ECMAScript中的参数在内部是用一个数组来表示的。函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。
  • 在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。

arguments对象:

arguments对象与数组类似(它并不是Array的实例):

  • 可以使用方括号语法访问它的每一个元素(即第一个元素是arguments[0],第二个元素是arguments[1],以此类推)。

例如:

        function sayHi(name, message) {
            return 'hello' + arguments[0] + ',' + arguments[1];
        };
        console.log(sayHi('张三', '123'));

在这里插入图片描述

  • 通过访问arguments对象的length属性可以获知有多少个参数传递给了函数。

例如:

        function howManyArgs() {
            console.log(arguments.length);
        }
        howManyArgs("string", 12);
        howManyArgs();
        howManyArgs(12);

在这里插入图片描述

ECMAScript中的所有参数传递的都是值,不可能通过引用传递参数。


7.2 没有重载

ECMAScript函数不能像传统意义上那样实现重载。

如果在ECMAScript中定义了两个名字相同的函数,则该名字只属于后定义的函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值