typeof
let s = 'string';
let n = 1;
let boo = true;
let nul = null;
let und = undefined;
let fun = function(){};
let obj = {
name: 'huihui',
age: 8
};
let arr = [1, 2, 3];
let sym = Symbol(1);
console.log(typeof(s)); // 'string'
console.log(typeof(n)); // 'number'
console.log(typeof(boo)); // 'boolean'
console.log(typeof(nul)); // 'object'
console.log(typeof(und)); // 'undefined'
console.log(typeof(fun)) // 'function'
console.log(typeof(obj)) // 'object'
console.log(typeof(arr)) // 'object'
console.log(typeof(sym)) // 'symbol'
typeof null 为什么返回 object
JS在底层存储变量的时候,会在机器的机器码的低位1-3位存储其类型信息
- 000:对象
- 010: 浮点数
- 100: 字符串
- 110: 布尔
- 1: 整数
Object.prototype.toSting.call()
let s = 'string';
let n = 1;
let boo = true;
let nul = null;
let und = undefined;
let fun = function() {};
let obj = {
name: 'huihui',
age: 8
};
let arr = [1, 2, 3];
let sym = Symbol(1);
console.log(Object.prototype.toString.call(s)); // [object, String]
console.log(Object.prototype.toString.call(n)); // [object, Number]
console.log(Object.prototype.toString.call(boo)); // [object, Boolean]
console.log(Object.prototype.toString.call(nul)); // [object, Null]
console.log(Object.prototype.toString.call(und)); // [object, Undefined]
console.log(Object.prototype.toString.call(fun)); // [object, Function]
console.log(Object.prototype.toString.call(obj)); // [object, Object]
console.log(Object.prototype.toString.call(arr)); // [object, Array]
console.log(Object.prototype.toString.call(sym)); // [object, Symbol]
instanceof
instanceof 主要的作用是判断一个实例是否属于某种类型
let person = function() {}
let notice = new person();
notice instanceof person // true
instanceof 也可以判断一个实例是否属于其父类型或者祖先类型的实例
let person = function(){}
let programmer = function(){}
programmer.prototype = new person();
let notice = new programmer();
console.log(notice instanceof person) // true
console.log(notice instanceof programmer) // true
instanceof 实现原理
function new_instance_of(leftVaule, rightVaule) {
let rightProto = rightVaule.prototype; // 取右表达式的 prototype 值
leftVaule = leftVaule.__proto__; // 取左表达式的__proto__值
while (true) {
if (leftVaule === null) {
return false;
}
if (leftVaule === rightProto) {
return true;
}
leftVaule = leftVaule.__proto__
}
}
其实instanceof主要的实现原理就是只要右边变量的prototype在左边变量的原型链上即可。
- 分析 Object instanceof Object
leftValue = Object.__proto__ = Function.prototype;
rightValue = Object.prototype;
// 第一次判断
leftValue != rightValue;
leftValue = Function.prototype.__proto__ = Object.prototype;
// 第二次判断
leftValue = rightValue
// 返回true
- 分析 Function instanceof Function
leftValue = Function.__proto__ = Function.prototype;
rightValue = Function.prototype;
// 第一次判断
leftValue = rightValue;
// 返回true
- 分析 Foo instanceof Foo
leftValue = Foo.__proto__ = Function.prototype;
rightValue = Foo.prototype;
// 第一次判断
leftValue = rightValue;
// 第二次判断
leftValue = Function.prototype.__proto__ = Object.prototype
leftValue != rightValue
// 第三次判断
leftValue = Object.prototype.__proto__ = null
leftValue != rightValue
// 返回false
- 分析 Foo instanceof Object
leftValue = Foo.__proto__ = Function.prototype;
rightValue = Object.prototype;
// 第一次判断
leftValue != rightValue;
// 第二次判断
leftValue = Function.prototype.__proto__ = Object.prototype
leftValue = rightValue
// 返回true
- 分析Foo instanceof Function
leftValue = Foo.__proto__ = Function.prototype;
rightValue = Function.prototype;
// 第一次判断
leftValue = rightValue;
// 返回true
总结
我们使用 typeof 来判断基本数据类型是 ok 的,不过需要注意当用 typeof 来判断 null 类型时的问题,如果想要判断一个对象的具体类型可以考虑用 instanceof,但是 instanceof 也可能判断不准确,比如一个数组,他可以被 instanceof 判断为 Object。所以我们要想比较准确的判断对象实例的类型时,可以采取 Object.prototype.toString.call 方法。