一、JS的对象和类型
JS中的所有事物都是对象,包括但不限于字符串、数值、数组、函数等等,还包括自定义对象。
在红宝书中,将JS分为五种基本类型:null、undefined、number、string、boolean和一种复杂类型:object。但是在《JavaScript语言精髓与编程实践》认为是6种:undefined、number、string、boolean、object和function,它的依据是typeof的结果只有6种(仅含ES自身,不包括宿主对象),其中null的类型也是object.
ES6新增了一种 Symbol 类型,它是一种不可变的类型,表示独一无二的值。一般作为对象属性的标识符使用。ES6 之前的属性名都是字符串类型,会造成属性名的重写覆盖。ES6 提出 Symbol 类型后,JS的基本类型即增加到了 7 种。
var
s1 = Symbol();
typeof
s1;
// "symbol"
var
s2 = Symbol(
'andy'
);
s2;
// Symbol(andy)
var
a = 1, b =
'2'
, c =
true
, d, e =
null
, f =
function
(){}
typeof
a ===
'number'
;
// true
typeof
b ===
'string'
;
// true
typeof
c ===
'boolean'
;
// true
typeof
d ===
'undefined'
;
// true
typeof
e ===
'object'
;
// true
typeof
f ===
'function'
;
// true
- null 返回值是 object ,因为解析器把 null 识别为了一个空值的对象。
- 正则表达式 /^\w*$/ 返回值是 object ,在一些老的浏览器返回值是 function。
- function 不属于数据类型,为什么用 typeof 会返回?
js 中函数也是对象,function 可以看成是 object 的一个子集。 - alert(typeof ii) 中的变量 ii 并没有定义,怎么也有返回值?
js 中规定未定义的变量使用 typeof 识别数据类型时也为 undefined 。
下面是七种基本类型的基本使用场景和方法:(引用链接: http://blog.csdn.net/baidu_32262373/article/details/52615158)
Undefiend 类型
1. Undefined 类型只有一个值,即: undefined 。
2.当用 var 声明一个变量但未初始化值时,此时 js 默认会给这个变量赋值,这个值是 undefined 。
var message; // 此时只声明了变量,未初始化,默认值为 undefined
alert(message); // 返回结果 undefined
3.为什么引入这个数据类型
首先我们得弄清一个概念 —— 去考试了但是考了0分 / 没有去考场,考卷上没有分数。
这个数据类型的创建就是为了解决这个问题。
我们声明了一个变量,只是没有给它赋值而已,它是一个实实在在的存在的东西。
和我们直接使用一个凭空出现的,尚未声明的不存在的变量是两个不同的概念。
var message; // 声明了变量 message
alert(message); // 返回结果 undefined,这个变量已经声明过了,只是没有初始化值
alert(apple); // 返回结果 控制台直接报错。
//(打开F12,选择 控制台或者Console 选项卡会看见红色报错信息)
4.总结
- 当控制台报错 : apple is not defined 时,应该迅速定位问题:我的 js 代码中没有定义这个变量,我需要考虑是否要声明这个变量。
- Undefined 类型的出现是为了区分:尚未初始化值的变量和尚未定义的变量。
Null 类型
1.Null 类型只有一个值,即: null 。
null 是空对象指针,对象里没有内容,即: null={ }; (注:js 中一对华括弧就是一个对象)
2.Null 和 Undefined 有什么关系?
Undefined 可以看成是 Null 的一个子集,下面的例子可以证实这一点:(了解有这回事,没多大卵用,知道 Null 和 Undefined 是两回事即可)
alert(null == undefined); // 返回结果 true
虽然 Undefined 和 Null 有关系而且很相似,为什么又要同时引入这两个概念呢?看下面。
3.Null 的用处?
如果一个变量被声明出来并且明确了在接下来的操作中会接收一个对象,那么就该显式的为该变量赋值 null 。
在下面的操作中只需要判断这个变量是否等于 null 就可以知道这个变量到底有没有储存一个对象。
var obj = null; // 定义了变量 obj ,并且已经明确这个变量下面就是用来接收对象
// ... obj 变量接收一个对象(对象即:键值对)
obj = {key1: 'value1', key2: 'value2'};
if (obj != null) {
// 判断 obj 如果不为 null,就说明此时已经储存了对象
}
4.总结
简单的说:
- undefined 的出现是为了区分 声明了但未初始化的变量和未定义变量之间的区别;
- null 的出现是为了更加方便的对对象进行处理。
Boolean 类型
1.Boolean 类型有两个值: true 和 false 。
2.常见误区:
- true 不一定等于数字 1,false 不一定等于数字 0 ;
- 由于 js 中区分大小写,因此 True 和 False 都不是 Boolean值。
3.类型转换
除 Boolean 类型外还有五种数据类型,都可以转换为 Boolean 类型。有两种方式:
1)使用 Boolean() 方法
var message = 'This is information';
var asBoolean = Boolean(message);alert(asBoolean); // 返回结果 true
- 2) 不适用任何方法,自带转换,常见于控制语句分支条件
var info = 'i am string';
if (info) {
// 这里的if(info)已经默认调用了Boolean()转换为了true,所以才会执行下面的 alert语句
alert(1); // 返回结果 1
}
4.其它四种数据类型转化为Boolean类型(不包括Null类型)
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | ”(空字符串) |
Number | 任何非零数字值(包括无穷大) | 0和NaN |
Undefined | 不适用 | undefined |
Object | 任何对象 | null |
Number 类型
1.进制数
十进制:js中默认的进制数
八进制:第一位必须是零,然后是0-7的数字组成
十六进制:前两位必须是0x,然后是0-9及A-F(字母不区分大小写)
例:
var num1 = 10; // 十进制
var num2 = 070; // 八进制的56
var num3 = 079; // 十进制,因为有数字超过了7,这里是79
var num4 = 0x1f; // 十六进制的31
注:
八进制在严格模式下("use strict")是无效的,会导致js报错,避免使用。
2.浮点值(即小数)
看个例子:
var num = 0.1 + 0.2;
alert(num); // 返回结果:0.30000000000000000004
上面例子表达的就是js的浮点型数据在计算时容易丢失精度,这一点并不仅在javascript存在,建议处理这方面问题使用专用的数字处理类,比如Java里的BigDecima类来处理。这里略过。
3.数字的范围
js中数值的范围是有效位数的,基本上够我们使用,我们仅需要知道以下几个知识点:
- 使用 Number.MIN_VALUE(或Number.NEGATIVE_INFINITY) 表示js中的最小值
- 使用 Number.MAX_VALUE(或Number.POSITIVE_INFINITY) 表示js中的最大值
- 如果某个值超出js的范围,就会转换为无穷大 Infinity 或 -Infinity
- 如果某次计算返回结果中有Infinity,该值无法参与下一次计算
使用 isFinite() 方法确认一个数值是否在js有效数值返回内
如:
var num = Number.MAX_VALUE + Number.MAX_VALUE;
alert(isFinite(num)); // 返回 false,无穷大加无穷大超出js数值范围
3.NaN (not a number)
问:为什么要引入这个东西?
答:在其他语言中,比如java中 1/0 由于0作为分母就会报错,但在js中就不会,直接返回NaN。
NaN的含义是本该返回数值的操作未返回数值,返回了NaN就不会抛出异常影响语句流畅性。
掌握:isNaN()的使用?判断一个值是不是数值,不是数值返回true,是数值返回false
如:
alert(isNaN(NaN)); // true 不是数值
alert(isNan(10)); // false 是数值
alert(isNan(false)); // false 自动转换为数值 0
alert(isNan('10')); // false 自动转换为数值 10
alert(isNan(hahah)); // true 不是数值
在上面的例子中,会发现有些值被自动的转换为了数值。这就和Boolean类型中的分支条件语句也会将所有数据类型自动转换Boolean一样。
if('hello'){ // 这里的'hello'被转换为了Boolean类型的true值
alert('i am print');
}
4.类型转换
就像Boolean类型有个Boolean()方法可以在某些情形下自动将其它数据类型转换为Boolean类型;
Number也提供了Number()方法在某些情形将其它数据类型转换为Number类型。
数据类型 | 返回结果 | 情形 |
---|---|---|
null | 返回0 | - |
undefined | 返回0 | - |
Boolean | true返回1,false返回0 | - |
String | ‘123’返回 123,’011’转换为 11 | 字符串中只包含数字,省略前导0 |
‘1.1’返回 1.1,’02.2’返回 2.2 | 字符串只包含小数,省略前导0 | |
‘0xf’返回 15 | 转换为十进制再返回 | |
”返回 0 | 空字符串转换为0 | |
- | 除字符串的其它情形返回NaN | |
Object | 待定 | 调用valueOf()方法再参照上述规则 |
parseInt()方法介绍:只能将字符串转换为数值型
如:
var num1 = Number('123abc'); // NaN
var num2 = Number('123abc'); // 123
问:为什么有Number()了还需要parseInt()方法?
答:比如上面的例子中使用Number()方法就不能返回数值,因为它要求字符串必须全部数值才行,而parseInt的解析字符串机制让它在某些情况下优于Number。
parseInt()处理机制:
首先解析字符串的第一个字符,如果不是数值直接返回,如果是数字,再接着往下解析,直到遇到不是数字的字符时停止,返回前面解析过的值。
使用parseInt()的好习惯是加上进制数。第二个参数定义转换的进制数。
如:
var num1 = parseInt('AF', 16); // 175
var num2 = parseInt('AF'); // NaN
上面例子中num1会返回数值,因为定义为了16进制数,而num2只是被当做普通字符串解析。
String 类型
1.类型转换
toString() 方法
- 几乎每个值都有toString()方法
- null和undefined没有toString()方法
- 数值、布尔值直接加引号转换为字符
- 对象的返回结果加引号转换为字符
对数值使用toString()时,可以加进制数限制结果
如:
var num = 10;
alert(num.toString(2)); // '1010'
alert(num.toString(8)); // '12'
String() 方法
由于toString()方法不能对null和undefined进行转换,那么当我们不确定这个值是不是null或undefined时如何转换呢?String()可以对任何值进行转换。
如:
var aa = null;
var bb;
String(aa); // 'null'
String(bb); // 'undefined'
Object 类型(引用链接:http://luopq.com/2016/02/28/Object-in-Javascript/)
Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的。虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是Object对象其实包含了很多很有用的属性和方法,尤其是ES5增加的方法,因此,本文将从最基本的介绍开始,详细说明了Object的常用方法和应用。
基础介绍
创建对象
首先我们都知道,对象就是一组相似数据和功能的集合,我们就是用它来模拟我们现实世界中的对象的。那在Javascript中,创建对象的方式通常有两种方式:构造函数和对象字面量。
new构造函数法
1
2
3
|
var
person =
new
Object();
person.name =
"狼狼的蓝胖子"
;
person.age = 25;
|
这种方式使用new关键字,接着跟上Object构造函数,再来给对象实例动态添加上不同的属性。这种方式相对来说比较繁琐,一般推荐使用对象字面量来创建对象。
对象字面量
对象字面量很好理解,使用key/value的形式直接创建对象,简洁方便。
1
2
3
4
|
var
person = {
name: “狼狼的蓝胖子”,
age: 25
};
|
这种方式直接通过花括号将对象的属性包起来,使用key/value的方式创建对象属性,每个属性之间用逗号隔开。
注意:如果是最后一个属性,后面就不要加逗号,因为在一些旧的浏览器下会报错。
对象实例的属性和方法
不管通过哪种方式创建了对象实例后,该实例都会拥有下面的属性和方法,下面将会一一说明。
constructor属性
constructor属性是保存当前对象的构造函数,前面的例子中,constructor保存的就是Object方法。
1
2
3
4
5
6
7
8
|
var
obj1 =
new
Object();
obj1.id =
"obj1"
;
var
obj2 = {
"id"
:
"obj2"
};
console.log(obj1.constructor);
//function Object(){}
console.log(obj2.constructor);
//function Object(){}
|
hasOwnProperty(propertyName)方法
hasOwnProperty方法接收一个字符串参数,该参数表示属性名称,用来判断该属性是否在当前对象实例中,而不是在对象的原型链中。我们来看看下面这个例子:
1
2
3
|
var
arr = [];
console.log(arr.hasOwnProperty(
"length"
));
//true
console.log(arr.hasOwnProperty(
"hasOwnProperty"
));
//false
|
在这个例子中,首先通过定义了一个数组对象的实例arr,我们知道数组对象实际是通过原型链继承了Object对象,然后拥有自己的一些属性,我们通过hasOwnProperty方法判断length是arr自己的属性,而hasOwnProperty是在原型链上的属性。
hasOwnProperty方法可以和for..in结合起来获取对象自己的key。
isPrototypeOf(Object)方法
isPrototype方法接收一个对象,用来判断当前对象是否在传入的参数对象的原型链上,说起来有点抽象,我们来看看代码。
1
2
3
|
function
MyObject() {}
var
obj =
new
MyObject();
console.log(Object.prototype.isPrototypeOf(obj));
|
我们知道MyObject是继承自Object对象的,而在JS中,继承是通过prototype来实现的,所以Object的prototype必定在MyObject对象实例的原型链上。
propertyIsEnumerable(prototypeName)方法
prototypeIsEnumerable用来判断给定的属性是否可以被for..in语句给枚举出来。看下面代码:
1
2
3
4
5
6
|
var
obj = {
name:
"objName"
}
for
(
var
i
in
obj) {
console.log(i);
}
|
执行这段代码输出字符串“name”,这就说明通过for…in语句可以得到obj的name这个属性,但是我们知道,obj的属性还有很多,比如constructor,比如hasOwnPrototype等等,但是它们没有被输出,说明这些属性不能被for…in给枚举出来,可以通过propertyIsEnumerable方法来得到。
console.log(obj.propertyIsEnumerable("constructor"));//false
判断“constructor”是否可以被枚举,输出false说明无法被枚举出来。
toLocaleString()方法
toLocalString方法返回对象的字符串表示,和代码的执行环境有关。
1
2
3
4
5
|
var
obj = {};
console.log(obj.toLocaleString());
//[object Object]
var
date =
new
Date();
console.log(date.toLocaleString());
//2016/2/28 下午1:39:27
|
toString()方法
toString用来返回对象的字符串表示。
1
2
3
4
5
|
var
obj = {};
console.log(obj.toString());
//[object Object]
var
date =
new
Date();
console.log(date.toString());
//Sun Feb 28 2016 13:40:36 GMT+0800 (中国标准时间)
|
valueOf()方法
valueOf方法返回对象的原始值,可能是字符串、数值或bool值等,看具体的对象。
1
2
|