JavaScript高级程序设计
文章目录
前言
本文章为JavaScript高级程序设计第三版的重点学习笔记,从第三章开始学习
三、基本概念
3.1.语法
- 区分大小写
- 标识符(变量、函数、属性的名字):
第一个字符为 字符、下划线(_)或 美元符号($)
其他字符可以是字母、下划线、美元符号、数字
应采用小驼峰格式
eg: myCar
注意:不能将关键字、保留字、true、 false、null用作标识符考,详见3.2
3.注释
// 单行注释
/*
* 多行注释
*
*/
4.严格模式
ES5引入严格模式, 全局使用,则在js顶部添加
"use strict"
,
局部使用可以在函数内部添加"use strict"
5.语句
可以使用分号结尾(推荐), 也可不使用, 其他语句也看自己开发的一个规范
3.2.关键字和保留字
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 |
红字为第五版新增的关键字
第三版定义的全部保留字:
abstract | enum | int | shot | 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 |
第五版非严格模式运行时保留字缩减为:
class | enmu | extends | super | const |
export | import |
第五版严格模式下:
implements | pacakge | public | interface | private |
static | let | protected | yield | eval |
个人认为以上所有关键字保留字 无需特别记忆,多写多看自然就知道了 尤其是有java基础的同学很多都是java的关键字哦
3.3.变量
JS是弱语言类型,每个变量可以用来表示任何类型
// 此时未初始化,变量会保存一个特殊值undefined
var message;
// 赋值为字符串h1,此时为字符串类型,同时可修改值的类型但不推荐
var message1 = 'hi';
message1=100
注意如果 在函数中使用var定义变量,则为局部变量,若在函数外使用则会报错
function test1() {
var message2 ="局部变量";
}
test1();
console.log(message2) // 错误
// 若函数中省略var操作符,则会将变量申明为全局变量(不推荐)
function test2() {
message2="全局";
}
test2();
console.log(message2); //全局
定义并初始化多个变量,以逗号分隔
var message = 'hi', flag=true, age='20';
3.4 数据类型
3.4.1 基本数据类型
Undefined、Null、Boolean、Number、String 可以使用typeof操作符来判断变量的数据类型
typeof操作符
typeof 可能会返回:string、number、boolean、object、undefined、function
需要注意的是 typeof null 返回的是object
console.log(typeof 'str'); // string
console.log(typeof 95); //number
console.log(typeof false); //boolean
console.log(typeof null) ; // object
console.log(typeof message); // undefined
console.log(typeof( function e() {})) // function
Undefined类型
Undefined类型只有一个值:undefined,当声明变量未初始化时,该变量的值就是undefined
Null类型
Null类型只有一个值:null。从逻辑角度来看,null值表示一个空对象指针,所以typeof检测null值会返回object
undefined值实际是派生自null值, 即两个值是相等的
console.log(null == undefined); // true
Boolean类型
两个值:true false
若要将一个值转为对应的Boolean值,可调用函数Boolean()
各数据类型及转换规则:
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | 空字符串 |
Number | 非零数字(包括无穷大) | 0、NaN |
Object | 任何对象 | null |
Undefined | / | undefined |
Number类型
var intNum = 10; // 十进制整数
var octalNum1 = 070; // 8进制56 ---八进制第一位必须是0,若数值超出范围,则前面的0会被忽略并整体当做十进制解析
var octalNum2 = 079; //无效,解析为79
var hxNum1= 0xA; // 十六进制10
浮点数
保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会将是整数的浮点数值转换为整数
var floatNum1 = 1.; // 解析为1
var floatNum2 = 1.0; //解析为1
对于极大或极小的值可以用科学计数法表示。
var floatNum3 = 3.125e7; // 3.125 * 10^7 = 31250000
var floatNum4 = 3e-7; // 3* 10^-7 = 0.0000003
浮点数的最高精度为17位,但在计算中仍然存在精度问题,例如0.1+0.2 不等于0.3 (注意精度问题是因为使用基于IEEE754数值的浮点计算的问题,并不是只有js会出现这样的问题)精度问题后面有空详细记录吧 毕竟也是面试常问
数值范围
ECMAScript 表示的最小数值 Number.MIN_VALUE = 5e-324;
最大数值Number.MAX_VALUE,大部分浏览器中这个数值是1.7976931348623157e+308, 若计算后超过数范围,则转成-Infinity / Infinity
NaN
即非数值, 例如任何数值除以0的结果都是NaN
NaN与任何值都不相等,包括NaN本身
若需要判断是否为NaN 可以使用isNaN()函数
console.log(isNaN(10)); //false
console.log(isNaN(NaN)); //true
数值转换
Number()
- Boolean值 true转换为1,false转换为0;
- 数字值,即转入和返回
- null值,返回0
- undefined,返回NaN
- 字符串
a. 只包含数字, '123’转换为123, '011’转换为11(即前导0会被忽略)
b. 只包含有效浮点, 转换为对应的浮点数值,同样会忽略前导0
c. 只包含有效的十六进制格式,转换为对应的十进制整数值
d. 空字符串,转为0
e. 包含其他字符,转换为NaN
parseInt()
转换字符串时,会忽略字符串前面的空格,直到找到第一个非空格字符。如果第一个字符不是数字字符或者负号,则会返回NaN;若第一个字符是数字符号,则继续解析直到遇到非数字或结束。
console.log(parseInt()); //NaN
console.log(parseInt('123abc')); // 123
console.log(parseInt('22.5')); // 22 (.是非数字符号所以只解析到22)
若解析的值是其他进制,则需要第二个参数表明解析值的进制 (默认10)
console.log(parseInt('0xAF', 16)); // 175
console.log(parseInt('AF', 16)); // 可省略0x
parseFloat()
只解析十进制值,十六进制格式的字符串始终会被转换成0
若解析的为’1.0’,返回的值为1
String类型
特殊的字符字面量(转义字符)可以出现在字符串中任意位置,并被当作1个字符来解析。
var text = "This is the letter sigma: \uD3A3."; // text有28个字符
字符串是不可变得,即字符串一旦创建,值不能改变。若要改变则需要先销毁再重新填充
var lang = 'java';
lang= lang + 'Script';
上述代码最终lang 为javaScript,看起来是改变了字符串,实际的操作过程是,首先创建一个能容纳10个字符的新字符串,再填充 java 和 Script,最后是销毁原来的java字符串和Script字符串。
转换为字符串的方式:
1.toString() null 和undefined值没有这个方法
同时可以传递参数:数值的基数。
var num = 10
console.log(num.toString()); // '10'
console.log(num.toString(2)); // '1010'
2.String() String(null)返回 'null'; String(undefined) 返回 'undefined'
3.4.2 引用类型
Object:属性和方法的集合, 是所有对象的基础
Array:表示数组对象,用于存储多个值的有序集合
Function:表示函数对象,用于执行特定的任务
Date:表示日期和时间的对象
Regexp:表示正则表达式的对象,用于进行模式匹配
此处只简单介绍Object类型,后续详见第五章内容
Object类型
是属性和方法的集合, 可通过new来创建var o = new Object()
Object的每个实例都具有下列属性和方法
- Constructor: 保存着用于创建当前对象的函数
- hasOwnProperty(propertyName): 用于检查给定的属性在当前对象实例中是否存在。
o.hasOwnProperty('name')
- isPrototypeOf(object): 用于检查传入的对象是否为另一个对象的原型
- propertyIsEnumerable(propertyName): 用于检查给定的属性是否能使用for-in来进行美剧
- toLocaleString(): 返回对象的字符串表示
- toString(): 返回对象的字符串表示
- valueOf(): 返回对象的字符串、数值或布尔值表示
3.5 操作符
3.5.1一元操作符
- 递增和递减: 前置型和后置型
var age = 29;
var age1 = ++age + 2;
console.log(age, age1); // 31, 33
var age2 = age-- +2;
console.log(age2); // 33
- 一元加和减操作符。
对于非数值应用医院加操作符时,会像Nubmer()转型函数一样对值进行转换。例如false – 0; true --1;对象是先调用valueOf() or toString()方法,再转换得到的值
var s1 = '01;
var s2='1.1';
var s3='z';
var b = false;
var f = 1.1
var o = {
valueOf: function () {
return -1;
}
}
s1 = +s1; //1
s2= +s2; // 1.1
s3=+s3; //NaN
b=+b; // 0
f=+f; //1.1
o=+f; //-1
一元减符号主要用于表示负数
3.5.2 位操作符
位操作符按内存中表示数值的位来操作数值。ECMAScript中所有数值都是以IEEE-754 64位格式存储,但位操作符先将64位转换为32位的整数,再执行操作,最后将结果转换为64位。
建议直接看计算机基础相关知识
按位非 ~ : 本质是操作数的负数-1
var num1 = 25; //00000000000000000000000000011001
var num2 = ~num1; //11111111111111111111111111100110
console.log(num2); //-26
按位与 &: 两个数值对应位都是1才返回1,任何一位0都是0
var num = 25 & 3; // 1
// 25: 0000 0000 0000 0000 0000 0000 0001 1001
// 3: 0000 0000 0000 0000 0000 0000 0000 0011
按位或|: 两个数值对应位上有一个是1就返回1, 两个位都是0返回0 console.log(25|3); //27
按位异或^: 两个数值对应位上只有1个1才返回1 console.log(25^3); //26
左移<<, 向左移动指定位数. 左移不会影响操作数的符号位。
eg: 2向左移动5位
console.log(2<<5); //1000000,对应十进制64
右移:
有符号的右移>>: 数值向右移动,但保留符号位
无符号的右移>>>: 正数无符号的右移结果与有符号的右移相同
console.log(64 >>> 5); // 二进制10 ,十进制2
console.log(-64 >>> 5); //00000111111111111111111111111110; 对应十进制134217726
3.5.3 布尔操作符
逻辑非!
console.log(!false); // true
console.log(!'blue'); // false
console.log(!0); // true
console.log(!NaN); // true
console.log(!''); // true
console.log(!123); // false
console.log(!null); // true
console.log(!undefined); //true
两个逻辑非!!, 得到这个值真正对应的布尔值,实际结果与对值使用Boolean()函数相同
console.log(!!false); // false
console.log(!!'blue'); // true
console.log(!!0); // false
console.log(!!NaN); // false
console.log(!!''); // false
console.log(!!123); // true
console.log(!!null); // false
console.log(!!undefined); //false
逻辑与(&&), 属于短路操作,即第一个操作数能决定结果后就不会对第二个操作数求值。对于逻辑与来说,如果第一个操作数是false,则结果为false。
但逻辑与操作可以应用于任何类型的操作数。当有一个操作数不是布尔值,结果可能不一定返回布尔值,规则如下:
1.第一个操作数是对象返回第二个操作数
2.第二个操作数是对象,则只有在第一个操作数求值结果为true的情况下返回该对象
3. 两个操作数是对象,返回第二个操作数
4. 有一个操作数是null/NaN/undefined,则返回null/NaN/undefined (这里的undefined是需要声明变量定义为undefined的值, 若没有声明变量进行判断 则第一个操作数为true或第一个操作数为未声明变量的值会导致报错
)
逻辑或||,同样是短路操作符。如果第一个操作符是true则不会对第二个操作数求值,结果返回为true。通常我们使用逻辑或来避免为变量赋值null或undefined。
3.5.4 乘性操作符
包含乘法*、除法/、求模%。 如果有一个操作数不是数值,则后台先调用Number()将其转换为数值再计算。
注意:
console.log(0/0); // NaN
console.log(1/0); //Infinity
console.log(-1/0); //-Infinity
3.5.5 加性操作符
加法+
- 两个操作数都是数值: 常规加法计算
- 两个操作数是字符串: 拼接
- 一个操作数是字符串: 将另一个操作数转换为字符串并拼接
减法- - 两个操作数都是数值: 常规减法计算 (-0 - -0 = +0; +0 - +0 = +0; +0 - -0 =-0)
- 有一个操作数是字符串、布尔值、null、undefined,现在后台踢调用Number()转为数值再计算。
- 有一个操作数是对象,则调用对象的valueOf()转为该对象的数值,或调用toString()将得到的字符串转换为数值
3.5.6 关系操作符
小于<、大于 >、小于等于 <= 、大于等于>=, 比较结果为布尔值
3.5.7相等操作符
相等== 、不相等!=: 比较时先强制转型再比较。例如一个操作数是字符串另一个是数值,会先将字符串转换为数值在比较
注意:
1.null和undefined相等
2.NaN!=NaN. 即若操作数中有一个为NaN 都为false
3.比较对象,若两个操作数指向同一个对象,则返回true
全等=== 不全等!== 两个操作数必须类型、数值都相等才返回true
此时 null !== undefined
3.5.8 其他操作符
1.条件操作符
即三元表达式 var max = num1 > num2 ? num1 : num2
如果num1大于num2 则将num1的值赋给max否则num2的值赋值给max
2.赋值操作符
3.逗号操作符
3.6 语句
if语句
if (i == 1) {
console.log('i=1');
} else if (i == 2) {
console.log('i=2');
} else {
console.log('i= else');
}
循环
var i = 0;
// do-while
do {
i +=2;
} while (i< 10);
// while
while ( i < 15) {
i++;
}
// for
for (var j = 0; i< 10; j++) {
console.log(j);
}
// for -in 枚举对象的属性,通常使用for-in来遍历key
// 注意:for-in 循环输出的key是不可预测的,因为js中对象的属性没有顺序。
const obj = { a: '1', b: '2'};
for (var key in obj) {
console.log(key, obj[key]);
}
// for-of 可以用于遍历数组、字符串、Map、Set、TypedArray 等可迭代对象。
// 通常使用 for-of 循环来遍历数组或字符串的值。
const arr = [1, 2, 3];
for (const value of arr) {
console.log(value);
}
break continue
通常用于控制在循环中的退出时机
break会立即退出循环,不在执行循环;continue会退出本次循环执行下一次
label
可以在代码中添加标签,通常与break continue结合使用。(不过日常开发中基本不用)
// break 跳出的是内循环 最终num = 23
var num = 0;
var i = 0, j;
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==3&&j==3){
break;
}
num++;
}
}
num = 0;
// countinue 只跳出1次i=3且j=3时 最终num = 24
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==3&&j==3){
continue;
}
num++;
}
}
// label break 此时break start会直接退出双层循环,跳到start的位置 最终num = 18
num = 0
start:
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==3&&j==3){
break start;
}
num++;
}
}
// countinue label
// continue会强制退出内部循环,执行外部循环,及不执行i =3 且j = 3 4 时,少执行2次 最终num = 23。
num = 0
start:
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==3&&j==3){
continue start;
}
num++;
}
}
switch语句
switch语句中可以使用任何数据类型, case值可以是变量、表达式
switch(expression) {
case value: statement
break;
case value: statement
break;
dafault: statement
3.7函数
使用function 来声明函数
基本语法:
function funcName(arg0, arg1) { statement}
参数
函数体内可以通过arguments对象来访问这个参数数组, arguments[0]访问第一个元素(但arguments不是array的实例)
function lenArgs () {
console.log(arguments.length)
}
lenArgs("str", 45); // 2
lenArgs(); //0
注意js中 没有函数重载
总结
- 基本数据类型: Undefined Null Boolean Number String; 使用typeof 来判断基础数据类型
- typeof null 返回的是object
- null == undefined 但 null !==undefined; NaN和任何值都不相等包括NaN
- JS 精度问题
- 使用arguments对象来访问函数参数