目录
简介
JS的每一个值,都属于一种数据类型。
JS的数据类型分为基本数据类型和引用数据类型(对象类型)
- 基本数据类型:数字类型、字符串类型、布尔类型、undefined类型、null类型
- 引用数据类型:对象、数组、函数
null和undefined
undefined表示一个“无”的原始值,null表示一个“无”的对象
undefined
undefined类型只有undefined这个值。当使用var声明后没有初始化时,就相当于给变量赋值了undefined
一般来说,不必将值显式地设置为undefined
值为undefined的常见场景
- 声明变量,但没有赋值,该变量的值为undefined(未声明的变量的值也是undefined)
var a; //a的值为undefined
- 调用了带参数的函数,但没有传参,该参数的值为undefined
function f(x){ return x } f(); //函数的参数x为undefined
- 函数没有返回值,默认返回undefined
function f(){ } var a=f(); //a的值为undefined
null
null类型只有一个值null,表示空指针对象。undefined是有null派生出来的。
布尔类型
如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。
- undefined、null、false、0、NaN、""、’’(空字符串)被转化为false值
- 其他被转化为true值
数字类型
在JS中,所有数值都是以浮点数形式存储,采用IEEE 754定义的双精度浮点数表示(和C语言的double一样)。
数值可以用字面形式表示,其他进制的数值会被转化为十进制表示。也可以用科学计数法表示。以下两种情况会自动转化为科学计数法表示
- 小数点前的数字多于21位
- 小数点后的0多于5个
在数值运算时,undefined转化为NaN,null转化为0
特殊值
NaN
表示“非数字”,下面情况会出现NaN值
- 将字符串错误解析成数字
var a=5-'x'; //a等于NaN
- 错误使用数学函数
var a=Math.log(-1); //a等于NaN
- 0除以0
var a=0/0;
运算规则
- NaN不等于任何值,包括NaN本身
- NaN与任何值(包括本身)的运算,都是等于NaN
- NaN在布尔运算中被当作false
Inifinity
Inifinity表示无穷大,有正负之分。下面情况会出现Inifinity
- 表达式的计算结果太大,超出了能够表达的范围
- 计算结果的极限为无穷,比如2/0
运算规则
- Inifinity大于任何值(NaN除外),-Inifinity小于任何值(NaN除外)
- 0*Inifinity结果为NaN
- Inifinity-Inifinity、Inifinity/Inifinity结果为NaN
- 与null运算相当于与0运算,与undefined计算相当于与NaN运算
全局方法
parseInt
将字符串转化为整数。有两个参数,第一个参数指定要转化的字符串;第二个参数指定解析字符串的进制,可选。返回结果为对应的十进制数。
基本用法
- 如果字符串头部有空格,空格会被自动去除
- 字符串转化为整数时,是一个一个字符依次转化的。遇到不能转化的字符(包括科学计数法的e),就不再进行下去,直接返回已经转好的部分。
- 如果第一个字符不能转化为数字,则返回NaN
- 如果第一个参数不是字符串,会将其转化为对应的数值表示,然后转化为字符串。
parseInt(0x11) // 等同于 parseInt('17') parseInt(1000000000000000000000.5) // 等同于 parseInt('1e+21') // 1 parseInt(0.0000008) // 等同于 parseInt('8e-7') // 8
指定进制
第二个参数值范围为2~36。如果不在这个范围,返回NaN。如果参数值为0、null、undefined,则直接忽略,使用默认的十进制解析。
和基本用法一致,从最高位解析,只返回可以转化的值。
parseInt('1564',2); // 1
parseFloat
将字符串转化为浮点数
与parseInt相同的是,会过滤掉前导空格。如果字符串包含不能转化为浮点数的字符,就返回已经转化好的部分。不同的是,如果参数不是字符串或者第一个字符不能转化为浮点数,直接返回NaN
字符串类型
字符串可以放在单引号和双引号之中。由于HTML的属性值使用双引号,一般使用单引号
字符串的特点
字符串是不可变的。一旦创建,值就不能变了。要修改某个变量的字符串值,就必须先销毁原先的字符串,然后把新字符串保存到该变量中
var lang="Java";
lang=lang+"Script";
整个过程首先会分配一个足够容纳10 个字符的空间,然后填充上
“Java"和"Script”。最后销毁原始的字符串"Java"和字符串"Script",因为这两个字符串都没有用
了。
字符串与数组
字符串可以使用数组的方括号运算符,用来返回某个位置的字符。如果方括号中的数字超过字符串的长度,或者方括号中根本不是数字,则返回undefined。
var str='123';
var a=str[0]; //a等于1
var b=str[4]; //b等于undefined
var c=str['x']; //c等于undefined
字符串和数组的相似性仅此而已,无法通过方括号运算符修改对应的字符
var str='123';
str[0]=3; //str还是等于'123'
length属性
length属性可以返回字符串的长度,该属性无法修改
var str='123';
var l=str.length; //l等于3
对象类型
对象就是一组键值对的集合,是一个无序的复合数据类型。
对象所有的键名都是字符串
- 如果键名符合标识符的条件,可以不加引号;反之则要
- 如果键名是数字,会自动转化为字符串
键值可以是任何数据类型,包括函数(把键值为函数的属性称为方法)。
对象的定义
直接上例子:注意键值对之间使用逗号隔开
var obj={
'name':'SKcong',
'universty':'SZU',
}
JS支持属性的后绑定:可以在任何时刻新增属性,没必要在定义对象时就定义好属性。
var obj={}
obj.name='SKcong';
obj.universty='SZU';
// 与上面的例子等价
对象的引用
类似于Java
属性的操作
读取、赋值
读取属性使用点运算符或者括号运算符,注意点如下:
- 使用括号运算符时,键名必须放在引号内,否则会被当成变量使用。数字键可以不加引号,会自动转化为字符串
- 数字键不能使用点运算符,会被当成小数点。
查看
使用Object.keys方法,参数为对象
keys方法用于查看自身属性
var obj={
'name':'SKcong',
'universty':'SZU',
}
Object.keys(obj); //['name','universty']
删除
使用delete命令,删除成功后返回true
var obj={
'name':'SKcong',
'universty':'SZU',
}
delete obj.universty;
注意:
- delete删除不存在的属性也会返回true。只有删除存在但不可删除的属性才会返回false
- delete无法删除继承的属性
in运算符
in用于检查对象是否包含某个属性(检查键名)。如果包含返回true,反之返回false
注意:in不能识别属性是属于本身的,还是继承的。可以使用hasOwnProperty判断。
var obj={
'name':'SKcong',
'universty':'SZU',
}
console.log(obj.hasOwnPropety('name')); //true
console.log(obj.hasOwnPropety('toString'); //false
for…in…
用于遍历属性
var obj = {a: 1, b: 2, c: 3};
for (var i in obj) {
console.log('键名:', i);
console.log('键值:', obj[i]);
}
// 键名: a
// 键值: 1
// 键名: b
// 键值: 2
// 键名: c
// 键值: 3
注意:
- 不仅遍历自身属性,还遍历继承属性
- 会跳过不可遍历的属性,比如’toString’
数组
数组属于一种特殊的对象。特殊性体现在键名是按次序排序的一组整数(实质上是字符串,因为JS会将数值键转化为字符串)。
length属性
数组的length属性,返回数组的成员数量
JS使用32位整数,保存数组的元素个数。所以数组成员最多只有232-1个,length最大值为232-1。
length属性是可写的
- 如果设置length小于当前元素个数,该数组的成员个数会自动减到设置的值。因此可以将length设置为0以实现清空数组
- 如果设置length大于当前元素个数,该数组的成员个数会自动增到设置的值,新增都是空位,值为undefined
可以将数组的键设置为字符串或者小数,结果不影响length属性。length属性的值等于最大的整数键加1
数组的空位
产生空位的情况
- 两个逗号之间没有任何值。注意:最后一个元素有逗号,并不会产生空位
var a=[1,,1]; // 产生空位 var a=[1,1,1,]; // 不会产生空位
- 修改length后产生的空位
- 使用delete删除一个数组成员,会产生一个空位
数组的空位是可以读取的,返回undefined。
但是,某个位置是空位与某个位置是undefined是不一样的。使用for……in……,forEach,Object.keys进行遍历时,空位会被跳过;而如果该位置是undefined,则不会
var a = [, , ,];
a.forEach(function (x, i) {
console.log(i + '. ' + x);
})
// 不产生任何输出
for (var i in a) {
console.log(i);
}
// 不产生任何输出
Object.keys(a)
// []
var a = [undefined, undefined, undefined];
a.forEach(function (x, i) {
console.log(i + '. ' + x);
});
// 0. undefined
// 1. undefined
// 2. undefined
for (var i in a) {
console.log(i);
}
// 0
// 1
// 2
Object.keys(a)
// ['0', '1', '2']
in运算符
用于检查某个键名是否存在
var arr=['a','b','c'];
2 in arr; //true
'2' in arr; //true
4 in arr; //false
如果某个位置是空位,则返回false
var arr=[];
arr[100]=100;
2 in arr; //false
遍历数组
- for……in……:不仅遍历数字键、而且遍历非数字键
- for、while:不过滤空位
- forEach
函数
声明
-
function命令
// 声明 function print(s){ console.log(s); } // 调用 print(1);
-
函数表达式
使用匿名方式
// 声明 var print=function(s){ console.log(s); } // 调用 print(1); //1
加上函数名,该函数名只是内部可用:一是可在函数体内部调用自身;二是除错工具显示函数调用栈时,将显示函数名,而不再显示这里是一个匿名函数
// 声明 var print=function f(s){ console.logs(s); } // 错误调用 f(1); // ReferenceError: x is not defined // 正确调用 print(1); //1
常用用法:var print=function print(s){};
如果函数重复声明,后面的声明会覆盖前面的声明
函数名的提升
JS引擎会将函数名视为变量名。
- 采用function声明函数时,整个函数的声明会被提升到代码头部。
- 采用函数表达式声明函数时,只是变量被提升
var f=function(){}; // 等同于 var f; f=function(){};
下面例子中,表面上后面声明的函数f,应该覆盖前面的var赋值语句,但是由于存在函数提升,实际上正好反过来。
var f=function(){
console.log('1');
}
function f(){
console.log('2');
}
// 等同于
var f;
function f(){
consoloe.log('2');
}
f=function(){
console.log('1');
}
f(); // 等于1
属性和方法
name
返回函数名字
如果是使用函数表达式声明,分两种情况
- 匿名函数
var f=function(){}; f.name; // 'f'
- 不匿名函数
var f=function print(){}; f.name; //'print'
length
返回定义的属性个数
toString
返回内容函数的源码,包括换行符,注释
原生函数返回的是 function name() {[native code]}
函数作用域
在ES5中,只有两种作用域:全局作用域和函数作用域。
ES6新增块级作用域。
函数内部定义的变量,在该作用域内会覆盖全局变量
函数内部的变量提升
在函数内部声明的变量,会被提升到函数头部
函数本身的作用域
函数执行时所在的作用域,是声明时的作用域,而不是调用时所在的作用域
var a = 1;
var x = function () {
console.log(a);
};
function f() {
var a = 2;
x();
}
f() // 1
参数
JS允许参数省略,也不限定传递参数的个数。省略的参数的值会变成undefined。
function f(a,b){
return a;
}
f(1,2,3); // 1
f(1,2); // 1
f(); // undefined
如果要省略前面的参数,只能显式传入undefined
function f(a,b){
return a;
}
f(,2); // SyntaxError: Unexpected token ,(…)
f(undefined,2); //undefined
如果有同名参数,取最后出现的那个值
传递方式
- 传值传递
- 传址传递:数组、对象、其他函数
arguments对象
这个对象只有在函数内部才能使用,包含函数运行时的所有参数。
arguments[0]是第一个参数、arguments[1]是第二个参数、……
可以通过arguments的length属性判断函数调用的参数个数
在严格模式下,无法通过arguments修改参数