一、javascript数据类型分为 基本数据类型和引用数据类型:
1.基本数据类型包括:number,string,boolean,undefined,null,es6 引入 Symbol()。
2.引用数据类型包括:Object(Array,Date,RegExp,Function)。
3.两者的区别:
基本数据类型:自身不可拆分的;值在内存中占据固定大小的空间,被保存在栈内存中;从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本;不能给基本类型的值添加属性。
引用数据类型:可以拆分很多细小的东西;值是指那些可以由多个值构成的对象,不能直接访问操作对象的内存空间;可以为其添加属性和方法,也可以改变和删除其属性和方法。
javascript中类型检测方法:
● typeof
● instanceof
● Object.prototype.toString
● constructor
● duck type
1.typeof 运算符返回一个用来表示表达式(的)数据类型(的)字符串;可能(的)字符串有:"number"、"string"、"boolean"、"object"、"function" 和 "undefined"。
1 <script>
2 console.log(typeof NaN) //返回值:number NaN特殊的非数字值
3 console.log(typeof Infinity) //返回值:number Infinity无穷大特殊值
4 console.log(typeof 123 ) //返回值:number
5 console.log(typeof '123') //返回值:string
6 console.log(typeof(true)) //返回值:boolean
7 console.log(typeof(Date)) //返回值:function
8 console.log(typeof(s)) //返回值:undefined 因为s作为一个变量未被定义,所以这里的返回值是undefined
9 console.log(typeof(undefined)) //返回值:undefined
10 console.log(typeof(document)) //返回值:object document是DOM下的一个对象
11 console.log(typeof(null)) //返回值:object
12 </script>
2.instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
object instanceof constructor
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。
1 // 定义构造函数
2 function C(){}
3 function D(){}
4 var o = new C();
5 o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype
6 o instanceof D; // false,因为 D.prototype不在o的原型链上
7 o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
8 C.prototype instanceof Object // true,同上
9 C.prototype = {};
10 var o2 = new C();
11 o2 instanceof C; // true
12 o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.
13 D.prototype = new C(); // 继承
14 var o3 = new D();
15 o3 instanceof D; // true
16 o3 instanceof C; // true
下面的代码使用了instanceof来证明:String和Date对象同时也属于Object类型。
1 var simpleStr = "This is a simple string";
2 var myString = new String();
3 var newStr = new String("String created with constructor");
4 var myDate = new Date();
5 var myObj = {};
6
7 simpleStr instanceof String; // returns false, 检查原型链会找到 undefined
8 myString instanceof String; // returns true
9 newStr instanceof String; // returns true
10 myString instanceof Object; // returns true
11
12 myObj instanceof Object; // returns true, despite an undefined prototype
13 ({}) instanceof Object; // returns true, 同上
14
15 myString instanceof Date; // returns false
16
17 myDate instanceof Date; // returns true
18 myDate instanceof Object; // returns true
19 myDate instanceof String; // returns false
20
21 function Car(make, model, year) {
22 this.make = make;
23 this.model = model;
24 this.year = year;
25 }
26 var mycar = new Car("Honda", "Accord", 1998);
27 var a = mycar instanceof Car; // 返回 true
28 var b = mycar instanceof Object; // 返回 true
3.为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为thisArg。
1 var toString = Object.prototype.toString;
2
3 toString.call(new Date); // [object Date]
4 toString.call(new String); // [object String]
5 toString.call(Math); // [object Math]
6
7 //Since JavaScript 1.8.5
8 toString.call(undefined); // [object Undefined]
9 toString.call(null); // [object Null]
4.constructor 属性返回对创建此对象的数组函数的引用,返回创建实例对象的 Object 构造函数的引用。注意,此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串。该值为只读的原始类型,如1,true和"test"。
所有对象都会从它的原型上继承一个 constructor 属性:
1 var o = {};
2 o.constructor === Object; // true
3
4 var o = new Object;
5 o.constructor === Object; // true
6
7 var a = [];
8 a.constructor === Array; // true
9
10 var a = new Array;
11 a.constructor === Array // true
12
13 var n = new Number(3);
14 n.constructor === Number; // true
5.duck type鸭子类型:
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。
比如不知道一个对象是不是数组,可以判断它的length是不是数字,它是不是有join,push这样一些数组的方法。通过一些特征判断对象是否属于某些类型,这个有时候也常用。
二、javascript类型转换:自动类型转换(隐式转换)和强制类型转换
javascript是弱类型语言,变量的类型是根据其实际值来决定的,变量在运行期间参与运算时,在不同的运算环境中,也会进行相应的自动类型转换。
自动类型转换一般是根运行环境和操作符联系在一起的,是一种隐式转换,看似难以捉摸,其实是有一定规律性的,大体可以划分为:转换为字符串类型、转换为布尔类型、转换为数字类型。
1.转换为字符串类型:
当加号“+”作为二元操作符(binary)并且其中一个操作数为字符串类型时,另一个操作数将会被无条件转为字符串类型。
1 // 基础类型
2
3 var foo = 3 + ''; // "3"
4
5 var foo = true + ''; // "true"
6
7 var foo = undefined + ''; // "undefined"
8
9 var foo = null + ''; // "null"
10
11
12 // 复合类型
13
14 var foo = [1, 2, 3] + ''; // "1,2,3"
15
16 var foo = {} + ''; // "[object Object]"
对于基础类型,会直接转为与字面量相一致的字符串类型,而对于复合类型,会先试图调用对象的valueOf()方法,如果此方法返回值是引用类型,则接着再调用其toString()方法,最后将返回值转为字符串类型。
2.转换为布尔类型:
a.数字转布尔类型,0和NaN会自动转为false,其余数字都被认为是true
b.字符串转为布尔类型,空字符串会被转为false,其它字符串都会转为true
c.undefined和null转为布尔类型,都被认为是false
d.对象转为布尔类型,只要当前引用的对象不为空,都会被认为是true
// 0和NaN为false,其余均为true
if (0) {
console.log('true');
} else {
console.log('false'); // output: false
}
if (-0) {
console.log('true');
} else {
console.log('false'); // output: false
}
if (NaN) {
console.log('true');
} else {
console.log('false'); // output: false
}
// 其余数字均为true
if (-3) {
console.log('true'); // output: true
} else {
console.log('false');
}
if (3) {
console.log('true'); // output: true
} else {
console.log('false');
}
// 空字符串为false
if (' ') {
console.log('true');
} else {
console.log('false'); // output: false
}
// 其他字符串均为true
if ('0') {
console.log('true'); // output: true
} else {
console.log('false');
}
if ('false') {
console.log('true'); // output: true
} else {
console.log('false');
}
// undefined和null都为false
if (undefined) {
console.log('true');
} else {
console.log('false'); // output: false
}
if (null) {
console.log('true');
} else {
console.log('false'); // output: false
}
// 字面量对象
var o = {
valueOf: function() {
return false;
},
toString: function() {
return false;
}
};
if (o) {
console.log('true'); // output: true
} else {
console.log('false');
}
// 函数
var fn = function() {
return false;
};
if (fn) {
console.log('true'); // output: true
} else {
console.log('false');
}
// 数组
var ary = [];
if (ary) {
console.log('true'); // output: true
} else {
console.log('false');
}
// 正则表达式
var regex = /./;
if (regex) {
console.log('true'); // output: true
} else {
console.log('false');
}
3.转换为数字类型:
a. 字符串类型转为数字,空字符串被转为0,非空字符串中,符合数字规则的会被转换为对应的数字,否则视为NaN
b. 布尔类型转为数字,true被转为1,false被转为0
c. null被转为0,undefined被转为NaN
d. 对象类型转为数字,valueOf()方法先试图被调用,如果调用返回的结果为基础类型,则再将其转为数字,如果返回结果不是基础类型,则会再试图调用toString()方法,最后试图将返回结果转为数字,如果这个返回结果是基础类型,则会得到一个数字或NaN,如果不是基础类型,则会抛出一个异常
1 var foo = +''; // 0
2
3 var foo = +'3'; // 3
4
5 var foo = +'3px'; // NaN
6
7 var foo = +false; // 0
8
9 var foo = +true; // 1
10
11 var foo = +null; // 0
12
13 var foo = +undefined; // NaN