变量和类型

288 阅读3分钟

变量

js的变量,说白了就相当于一个存储数据的‘容器’, 我们在定义变量是需要注意一下几点:

  • 变量名对大小写敏感;
  • 变量名必须以字母开头(也可以以$ 和 _ 符号开头,但是不建议);

JavaScript规定了几种语言类型

JavaScript 规定的数据类型有七种: Number,String,Boolean,null, undefined,Symbol,Object。

  • 基本类型有6种:Number,String,Boolean,null, undefined,Symbol。
  • 引用数据类型类型只有1种:Object(在 JavaScript 种除了基本类型以外都是对象, Date,function, Array, 正则表达式都是对象)
扩展
  1. 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() 这个方法既可以判断原始类型又可以判断引用类型,但是对于对象的继承关系却无能为力。