js有7种内置类型
其中:
基本数据类型6个:
string、number、Boolean、null、undefined、symbol(ES6新的原始数据类型,代表独一无二的值)
引用类型1个:
object
但是引用类型又包含:array、function、object,这三个数据类型陈伟复杂的数据类型
判断是否字符串:
let a = "123";
console.log(typeof a); // string
console.log(a instanceof String); // false
console.log(a.constructor === String) // true
console.log(Object.prototype.toString.call(a) === '[object String]'); // true
判断是否数字:
let a = 123;
console.log(typeof a); // number
console.log(a instanceof Number); // false
console.log(a.constructor === Number) // true
console.log(Object.prototype.toString.call(a) === '[object Number]'); // true
判断是否数组:
let a = [1, 2, 3];
console.log(typeof a); // object
console.log(typeof a == Array); // false
// instanceof
console.log(a instanceof Array); // true
// constructor
console.log(a.constructor == Array); // true
// 此方法比较繁琐,但是管用
console.log(Object.prototype.toString.call(a) === '[object Array]'); // true
判断是否对象:
let a = new Object;
a.color = "red";
console.log(a); // {color: "red"}
console.log(typeof a); // object
console.log(a instanceof Object); // true
console.log(a.constructor == Object); // true
console.log(a.constructor = "changeObjectType") // 修改对象的constructor属性(是可修改的)
console.log(a.constructor == Object); // false
console.log(Object.prototype.toString.call(a) == '[object Object]'); // true
console.log(a.toString() == '[object Object]'); // true 对象类型可以直接调用toString方法
判断是否函数方法:
let a = function () {}
console.log(a); // ƒ () {}
console.log(typeof a); // function
console.log(a instanceof Function); // true
console.log(a.constructor == Function); // true
console.log(Object.prototype.toString.call(a) == '[object Function]'); // true
从上面的测试例子可以看到:基本数据类型使用typeof方法检测(null返回object);引用数据类型使用instanceof方法检测;万能方法是对象的原生toString()方法;不推荐使用constructor方法检测数据类型,因为这是可修改的、容易发生变化的。
以上方法只针对页面上只有一个全局window对象的情况下,是没有任何问题的。但是当页面有多个iframe的时候,页面上就会有多个window对象。此时使用instanceof或者toString方法来判断数据类型的话都会出问题,来一个例子看看吧。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>test iframe</title>
</head>
<body>
<script>
var arr3 = ["iframe1", "iframe2", "iframe3"];
</script>
</body>
</html>
<iframe id="iframe" src="test.html" frameborder="0"></iframe>
<script>
var iframe = document.getElementById("iframe").contentWindow;
console.log(iframe.window);
var arr = [1, 2, 3];
var arr3 = iframe.window.arr3;
console.log(Object.prototype.toString.call(arr)); // [object Array]
console.log(Object.prototype.toString.call(arr3)); // [object Undefined]
console.log(iframe.window.Object.prototype.toString.call(arr3)); // [object Undefined]
alert(Array.isArray(arr)); // true
alert(Array.isArray(arr3)); // false
alert(arr instanceof Array) // true
alert(arr3 instanceof Array) // false
</script>
很明显,获取到iframe里面的数组对象arr3之后,调用对象toString方法打印出是undefined类型,所以在后面无论是使用什么方法都无法证实arr3这个对象是数组类型。其实这里我也有一个很大的疑问,在JavaScript高级程序设计这本书中,说是任何值调用Object原生的toString()方法都会返回一个[object NativeConstructorName]格式的字符串;每个类在内部都有一个[[Class]]属性,这个属性中就指定了上述字符串中的构造函数名。然而在这里为什么会返回undefined呢?期待大佬帮忙解答。