javascript中一种有6中数据类型,有5种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number 和String,还有1种复杂数据类型——Object。
1、Undefined
Undefined 类型只有一个值,即特殊的undefined。根据工作中总结,只要有这几种情况下会出现undefined。1.定义变量,但是没有初始化时,如var a;
2.调用某个函数时,实参个数小于形参个数时,未实参化的形参在函数调用过程中的值是undefined;
3.调用某个对象还没有添加的属性时,也会返回undefined;
var obj={}
console.log(obj.name);//undefined
复制代码
4.调用某个没有返回值的函数,也会返回undefined;
function Person(name,age){
this.name=name;
this.age=age;
}
var p=Person("李四",23);//此时的p=undefined;
复制代码
5.对未初始化的变量执行 typeof 操作符会返回 undefined 值;
6.对未声明的变量执行 typeof 操作符同样也会返回 undefined 值。
var message; // 这个变量声明之后默认取得了 undefined 值
//未初始化的变量
alert(typeof message); // "undefined"
//未申明的变量
alert(typeof age); // "undefined"
复制代码
2、Null 类型
是第二个只有一个值的数据类型,这个特殊的值是 null。从逻辑角度来看,null值表示一个空对象指针,要意在保存对象的变量还没有真正保存对象。而这也正是使用 typeof 操作符检测 null值时会返回"object"的原因。这几种情况下会出现null的情况1、手动设置变量的值或者对象某一个属性值为null(在初始化对象时,手动设置对象为null。在作用域中不再需要使用某个对象时,把null赋值给那个变量解除引用,以释放内存)
2、在javascript的DOM元素获取中,如果没有获取到指定的元素对象,结果一般是null。
var d=document.getElementById("d");
console.log(d);//当没有id为"d"的标签时返回null
复制代码
3、Object.prototype._proto_的值也是null。(每一个对象都有__proto__属性,指向对应的构造函数的prototype属性,但是因为Object是所有类的基类,其没有对应的构造函数,所有Object.prototype._proto_值为空);
console.log("a".__proto__);
//指向的是String的prototype属性
//String {"", length: 0, constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ, …}
复制代码
4、在正则捕获的时候,如果没有捕获到结果,默认也是null。
注意:实际上,undefined 值是派生自 null值的。undefined转为数值为NAN,而null转为数值却为0
alert(typeof null);//object
alert(null == undefined);弹出的是true
alert(Number(undefined));//NAN
alert(Number(null))//0
复制代码
3、Boolean类型
这个类型需要注意的值它的两个字面量true和false是区分大小写的。还要注意其他类型转换为此类型的情况。
数据类型 | 转换为true的值 | 转换为true的值 |
---|---|---|
String | 任何非空字符串 | 空字符串("") |
Number | 任何非零数值(包括无穷大) | 0和NAN |
Object | 任何对象 | null |
Undefined | 没有为true的情况 | undefined |
4、Number
注意点1:Number的浮点数值在进行算术计算时精确度远远不如正数,所以不要去计算两个浮点数相加的结果是否等于另一个浮点数。
if(0.1+0.2==0.3){
alert("相等")
}
这种情况永远都不会弹出"相等"的。因为浮点数的精度太高,0.1+0.2的值不一定精确的等于0.3。
复制代码
注意点2::NaN,即非数值(Not a Number)是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。
NaN 本身有两个非同寻常的特点。
1、任何涉及 NaN 的操作(例如 NaN/10)都会返回 NaN,这个特点在多步计算中有可能导致问题。
2、NaN与任何值都不相等,包括 NaN 本身。
针对 NaN 的这两个特点,ECMAScript定义了 isNaN()函数。这个函数接受一个参数,该参数可以 是任何类型,而函数会帮我们确定这个参数是否“不是数值”。任何不能被转换为数值的值都会导致这个函数返回 true。
注意点3:数值转换 有三个函数可以将非数值转换为数值:Number()、parseInt()、parseFloat()。Number()可以用于转换任何数据类型,而另外两个只能将字符串转换为数值。
4.1 Number()函数的转换规则如下所示
-
如果是Boolean类型,true和false分别转换为1和0.
Number(true);//1 Number(false);//0 复制代码
-
如果是null值,返回0。
-
如果是undefined,返回NAN
Number(null);//0 Number(undefined);//NAN 复制代码
-
如果是String类型,需要考虑以下情况。
1、如果字符串中只包含数字,则直接将其转换为10进制数值,并且会忽略前导0。如"123"会变成123,"011"会变成11,"1.1"会变成1.1。
2、字符串中包含有效的十六进制格式,则会将其转换为相同大小的10进制整数值。 3、如果字符串为空的,则将其转换为0。
4、除上面三种情况外,都会转换为NAN。 -
如果是Object类型,则调用对象那个的valueOf(),依照前面的规则转换返回的值。不过一般不会将对象去转换成对应的数值。一般情况下对象转换成数值都是返回NAN。
Number({a:123});//NAN 复制代码
4.2 parseInt()转换规则
在转换字符串时更多的是看其是否符合数值格式,它会自动忽略字符串前面的空格,直到找到第一个非空字符串,如果是非数值字符串就直接返回NAN,如果是数值字符串则会一直匹配到非数值字符串处结束。 并且转换空字符转时会返回NAN。parseIn也能够识别出各种正数格式(八进制、十六进制)。做这种转换时需要传递第二个参数,不然分辨不出八进制格式的数据。
parseInt(" s");//NAN
parseInt("s");//NAN
parseInt(" 2s");//2
parseInt("");//NAN
parseInt("0xA",16);//10(十六进制)
parseInt("070");//70
parseInt("070",8);//56
复制代码
4.3 parseFloat转换规则
parseFloat跟parseInt的解析规则类似。区别在于: 它只解析十进制值,没有第二个参数指定基数 。5、String类型
这里在价格其他类型的值转换为字符串时,主要遵循如下规则。
1、如果值有 toString()方法,则调用该方法(没有参数)并返回相应的结果;
2、如果值是 null,则返回"null";
3、如果值是 undefined,则返回"undefined"。
var value1 = 10;
var value2 = true;
var value3 = null;
var value4;
alert(String(value1)); // "10"
alert(String(value2)); // "true
alert(String(value3)); // "null"
alert(String(value4)); // "undefined"
复制代码
主要有以下方法:
1、字符方法
charAt(index):返回给定位置的字符,index未指定时,默认为0。
charCodeAt(index):返回指定位置的字符编码,index未指定时,默认为0。 。
fromCharCode():接收一个或多个字符编码,然后将他们转换为字符串。从本质上看是charCodeAt()的相反操作。
console.log(String.fromCharCode(104,102,103,106));//"hfgi"
var str="hijhj"
console.log(str.charAt());//"s",index未指定时,默认为0
console.log(str.charAt(1));//"i"
console.log(str.charCodeAt());//104
console.log(str.charCodeAt(1));//105
复制代码
2、字符串操作方法
字符串拼接:concat(),不会改变字符串本身,会返回一个新的字符串。
字符串分割:slice()、substr()、substring()。不会改变字符串本身,会返回一个新的字符串。他们之间的区别如下。
方法 | 第一个参数 | 第二个参数 |
---|---|---|
slice | 表示切割的起点(默认值为0),为负数时会将负值与字符串的长度相加作为索引起点 | 表示切割的终点(默认值为字符串的长度),为负数时会将负值与字符串的长度相加作为索引终点 |
substr | 表示切割的起点,为负数时会将负值与字符串的长度相加作为索引起点 | 表示切割的个数,为负数时自接转换为0 |
substring | 表示切割的起点,为负数时自接转换为0 | 表示切割的终点,为负数时自接转换为0 |
var str="hello world";
console.log(str.slice());//hello world
console.log(str.slice(1,3))//el
console.log(str.slice(-1,-3))//""
console.log(str.substring());//hello world
console.log(str.substring(1,3));//el
console.log(str.substring(-1,-3))//""
console.log(str.substr())//hello world
console.log(str.substr(1,3));//ell
console.log(str.substr(-1,-3))//""
复制代码
3、字符串位置方法
indexOf(str,index)和lastIndexOf(str,index):用于从指定字符串中指定位置(index,默认是0)开始搜索str,返回str第一次出现的位置的索引值。只不过indexOf()是从开头向后搜索,lansIndexOf反之。
4、trim()方法
用于删除字符串前置和后缀的所有空格。
5、字符串大小写转换方法
toLowerCase() 将字符串全部转换为小写; toUpperCase() 将字符串全部转换为大写。还有针对特定地区的方法如:toLocaleLowerCase() 将字符串全部转换为小写;toLocaleUpperCase() 将字符串全部转换为大写。建议一般情况下使用针对地区的方法。
6、字符串的模式匹配方法
match(): 只接受一个参数,要么是正则表达式,要么是RegExp对象,返回一个数组。本质上于RegExp的exec()方法相同。
var str="hello world";
var pattern=/llo/;
var matches=str.match(pattern);
console.log(matches)
复制代码
search(): 与match方法的参数相同,要么是正则表达式,要么是RegExp对象。返回字符串中第一个匹配项的索引。如果没有匹配上则返回-1。并且始终从字符串开始向后查找。
var str="hello world";
var pattern1=/llo/;
var pattern2="lloe"
var index1=str.match(pattern1);//2
var index2=str.match(pattern2);//-1
复制代码
replace(): 接收两个参数,第一个参数可以是RegExp对象或者字符串,第二个参数是一个字符串或者一个函数。第一个参数是字符串时,name只会替换第一个子字符串。要想替换所有的子字符串,必须提供正则表达式,而且要指定全局(g)标志。
var str = "hello world";
var res1 = str.replace("l", "ww");
console.log(res1); // hewwlo world
var res2 = str.replace(/l/g, "ww");
console.log(res2);//hewwwwo worwwd
复制代码
如果第二个参数为字符串,还可以使用一些特殊的字符序列。
实例如下: var str="hello world hello hello";
var res=str.replace(/(.ll)/g,"123($1)");
console.log(res);//h123(ell)o world h123(ell)o h123(ell)o
复制代码
如果第二个参数为函数,在只有一个匹配项的情况下,会向这个函数传递3个参数:模式的匹配项,模式匹配项在字符串中的位置和原始字符串。 function(match,pos,originalText) 。如果是有过个捕获组的情况下,传递给函数的参数依次是模式的匹配项,第一个捕获组的匹配项,第二个捕获组的匹配项。。。,最后两个参数仍然是模式匹配项在字符串中的位置和原始字符串。
split(): 基于指定的分隔符将字符串分割为多个子字符串。并返回一个数组。分隔符可以是字付串也可以是RegExp对象。还可以接受第二个参数,用于指定返回数组的大小。
var str="tre,rwr,rewr,rwrew";
var res1=str.split(",");
var res2=str.split(",",2);
var res3=str.split(/[^\,]+/);//表示以多个非","进行分割
console.log(res1);//(4) ["tre", "rwr", "rewr", "rwrew"]
console.log(res2);//(2) ["tre", "rwr"]
console.log(res3);//(5) ["", ",", ",", ",", ""]
复制代码
7、localeCompare()方法
用于比较两个字符串。 如果字符串再字母表中排在传入字符串参数之前,则返回一个负数,反之则是一个整数,相等时返回0。
var str="bbc";
alert(str.localeCompare("cca"));//-1
alert(str.localeCompare("aca"));//-1
alert(str.localeCompare("bbc"));//0
复制代码
8、HTMl方法
但是尽量不去使用这些方法,因为他们创建的标记通常无法表达语义。
6、Object类型
主要是注意这几个方法:hasOwnProperty(propertyName): 用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定(例如:o.hasOwnProperty("name"))。
isPrototypeOf(object): 用于检查传入的对象是否是传入对象的原型。
propertyIsEnumerable(propertyName): 用于检查给定的属性是否能够使用 for-in 语句 (本章后面将会讨论)来枚举。与 hasOwnProperty()方法一样,作为参数的属性名必须以字符串形式指定。
getKeys(obj): 返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
getValues(obj): 返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。属性名为数值的属性,是按照数值大小,从小到大遍历的。