类型
分为两种类型
原始(值)类型
Undefined
Null
Boolean
String
Number
对象(引用)类型
var obj = {};
var arr = [];//数组类型
var date = new Date();//所有用new 构造函数赋值的变量
对象类型
JS中所有对象的分类
浏览器扩展对象
是各个浏览器厂商为自己扩展的JS对象
宿主对象
是浏览器环境所提供的对象,这些对象提供了DOM的操作,比较重要的概念
原生对象
分为两类
1. 构造函数:利用规范的构造函数定义的一系列对象
2. 对象:内置对象。Math JSON arguments 全局对象….
这写对象统称为原生对象
原始类型和对象类型的区别
原始类型存储与栈内存
而对象类型则将实际数据存储于堆内存
如下图:
复制的区别,对象类型间复制时传递的是指针,原始类型则是值
如下图:
隐式类型转换
<body>
10 + <input type="text" id="num"/><input type="button" value="等于" id="btn"/><span id="ret"></span>
<script type="text/javascript">
var btn= document.getElementById('btn');
var num = document.getElementById('num');
var ret = document.getElementById('ret');
btn.addEventListener('click',function(){ret.innerText= 10 + num.value;
})
</script>
</body>
注意:除了+运算符以外,当数值和字符进行运算时,会将字符转换为数字计算。
用+运算符则会将数值转换为字符。
哪些场景会导致隐式类型转换的情况
- 数字运算符
加号+ 当一端是字符串一端是数字时,会将数字转换为字符串。
- .
所有直接量通过.号去调用某个方法时,JS运行环境将会隐式转换这个直接量为相应对象类型。
比如"hello world".split(" ");//[hello,world]
- if语句
if语句的条件部分的最终会被转换为布尔值。
- ==
双等号运算符
隐式类型转换结果
如下图
大部分是符合预期的。但是尤其要注意图上红色标注部分
undefined——->Number时:NaN
null ———->Number :0
“” ——–>Booleam :false
“la” ——->Number: NaN
NaN ——–>Boolean: false
Object —–>Boolean: true
Object ——–>Number: NaN
当隐式类型转换不符合预期时可以使用显示转换
显示类型转换方法如下:
- Number(), String(), Boolean()
Number()方法将字符串转换为数字
String()方法将所有在参数内的都转换为字符串
Boolean()将参数中的对象转换为布尔值
- parseInt(), parseFloat()
将数字转换为整型和浮点型
- !, !!
!!将获取对象的布尔值
类型识别
为什么要类型识别
比如要实现以下函数function toDate(param){}
传入参数有可能是各种类型。返回结果要求为Date.
/*
*输入格式
*'2015-08-06'
*1438744815232
*{y:2015,m:8, d:5 }
*[2015,8,5]
*返回格式:Date
*/
function toDate(param){
if(typeof(param) == 'string' || typeof(param) == 'number'){
return new Date(param);
}
if(param instanceof Array){
var date = new Date(0);
date.setYear(param[0]);
date.setMonth(param[1]-1);
date.setDate(param[2]);
return date;
}
if(typeof(param) == 'object'){
var date = new Date(0);
date.setYear(param.y);
date.setMonth(param.m-1);
date.setDate(param.d);
}
return -1;
}
注意:程序中将数组的识别放在了对象的识别之前。这是有原因的。
类型识别的方法
- typeof
- instanceof
- Object.prototype.toString.call
- constructor
typeof
typeof是一个操作符
可以识别标准类型(Null除外)
不能识别具体的对象(除了Function对象外)
typeof "jerry"; //"string"
typeof 12; //"number"
typeof true; //"boolean"
typeof undefined; //"undefined"
typeof null; //"object"
typeof { name:"jerry"}; // "object"
typeof function();//"function"
null类型被识别为对象类型
instanceof
1能判别内置对象类型
不能判别原始类型
2可以判别自定义对象类型
综合1 和2 说明instanceof 能识别所有对象类型
//能够判别内置对象类型
[] instanceof Array; //true;
/\d/ instanceof RegExp; //true;
//不能判别原始类型
1 instanceof Number; //false
"jerry" instanceof String; //false
//识别自定义对象类型,及其父子对象
function Point(x, y){
this.x = x;
this.y = y;
}
function Circle(x, y, r){
Point.call(this, x, y);
this.radius = r;
}
Circle.prototype = new Point();
Circle.prototype.constructor = Cricle;
var c = new Circle(1, 1, 2);
c instanceof Circle //true
c instanceof Point //true
Object.prototype.toString.call
可以识别标准类型以及内置对象类型
不能识别自定义对象类型
封装一个函数
function type(obj){
return Object.prototype.toString.call(obj).slice(8,-1);
}
//识别标准类型以及内置对象类型
type(1); //"Number"
type("abc"); //"String"
type(true); //"Boolean"
type(null); //"Null"
type({}); //"Object"
type([]); //"Array"
type(new Date);//"Date"
type(/\d/); //"RegExp"
type(function(){}); // "Function"
//不能识别自定义对象类型
function Point(x, y){
this.x = x;
this.y = y;
}
type(new Point(1, 2)); //"Object",不能识别对象的具体类型
constructor
constructor就是构造这个函数的构造本身,就是指向构造函数的指针。利用这个特性获得构造函数的名称就能知道对象类型
- 判别标准类型(Undefined/Null除外)
为什么Undefined Null除外,因为它们没有构造函数 - 列表内容判别内置对象类型
- 判别自定义对象类型
//获取对象构造函数名称
function getConstructorName(obj){
return obj && obj.constructor && obj.constructor.toString().macth(/function\s*([^(]*)/)[1];
}
getConstructorName([]) ==="Array"; //true