变量
js的变量,说白了就相当于一个存储数据的‘容器’, 我们在定义变量是需要注意一下几点:
- 变量名对大小写敏感;
- 变量名必须以字母开头(也可以以$ 和 _ 符号开头,但是不建议);
JavaScript规定了几种语言类型
JavaScript 规定的数据类型有七种: Number,String,Boolean,null, undefined,Symbol,Object。
- 基本类型有6种:Number,String,Boolean,null, undefined,Symbol。
- 引用数据类型类型只有1种:Object(在 JavaScript 种除了基本类型以外都是对象, Date,function, Array, 正则表达式都是对象)
扩展
- Symbol Symbl是ES6引入的一种新型原始数据类型,表示独一无二的值。
类型判断
1.使用 typeof
不管三七二十一先来段代码:
console.log(typeof 123) // number
console.log(typeof "123") // string
console.log(typeof true) // boolean
console.log(typeof Symbol('typeof')) // symbol
console.log(typeof undefined) // undefined
console.log(typeof function(){}) // function
console.log(typeof null) // object
console.log(typeof {}) // object
console.log(typeof []) // object
从上面的代码可以看出 typeof 可以判断大部分的基本类型(number, string, boolean,symbol, undefined),但是null被判断为 Object(历史遗留问题)。
大部分的引用类型都判断为 Object,但是 function 除外。
总结
typeof 可以判断基础类型:Number,String,Boolean, undefined,Symbol的数据类型(null除外)以及function的类型。
2.使用instanceof
还是老办法,用代码开路
// instanceof
function Person () {
this.name = '张三'
}
let P = new Person();
console.log([] instanceof Array) // true
console.log({} instanceof Object) // true
console.log(function () {} instanceof Function) // true
console.log(P instanceof Person) // true
console.log(function () {} instanceof Object) // true
console.log([] instanceof Object) // true
console.log(P instanceof Object) // true
从代码中基本可看出 instanceof 对于引用类型的判断真是无往不利啊,不管是自定义对象,还是Object, Array,Function都可以给出一个准确的判断。但是[] instanceof Object, function () {} instanceof Object 返回的都是 true。这是为什么呢?
这是因为 instanceof 是原型链来实现的。instanceof会一级一级的查找原型对象,直到找到目标对象返回 true,或者到Object都没有找到则返回 false。
虽然 instanceof 已经很厉害了但是,依然有很多短板
console.log(null instanceof Object) // false
console.log(1 instanceof Number) // false
console.log('123' instanceof String) // false
console.log(true instanceof Boolean) // false
console.log(Symbol('1') instanceof Symbol) // false
// console.log(undefined instanceof undefined) // Right-hand side of 'instanceof' is not an object
发现 instanceof 对原始类型真的是一点办法都没有呀。而且 instanceof右边不是一个Object的话还会抛出异常。
总结:
instanceof 只能测试用 new声明的对象,而且还可以监测对象的继承关系,但是对于原始类型以及undefined和null一点办法都没有。
3.使用Object.prototype.toString.call
function Person () {
this.name = '张三'
}
let P = new Person();
console.log(Object.prototype.toString.call(1)) // [object Number]
console.log(Object.prototype.toString.call('1')) // [object String]
console.log(Object.prototype.toString.call(true)) // [object Boolean]
console.log(Object.prototype.toString.call(null)) // [object Null]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(Symbol('123'))) // [object Symbol]
console.log(Object.prototype.toString.call({})) // [object Object]
console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(P)) // [object Object]
console.log(Object.prototype.toString.call(function(){})) // [object Function]
console.log(Object.prototype.toString.call(new Date())) // [object Date]
原理(摘自高级程序设计3):在任何值上调用 Object 原生的 toString() 方法,都会返回一个 [object NativeConstructorName] 格式的字符串。每个类在内部都有一个 [[Class]] 属性,这个属性中就指定了上述字符串中的构造函数名。 但是它不能检测非原生构造函数的构造函数名。
总结
Object.prototype.toString.call() 这个方法既可以判断原始类型又可以判断引用类型,但是对于对象的继承关系却无能为力。