一、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