# 摘录于typeof和instanceof原理
# 摘录于instanceof原理
JS数据类型
基本数据类型(7):
null
undefined
boolean
number
string
symbol(符号,ES6中新增):表示独一无二的值
bigint(大整数,ES2020引入):用来解决 JavaScript中数字只能到 53 个二进制位(JavaScript 所有数字都保存成 64 位浮点数,大于这个范围的整数,无法精确表示的问题
引用数据类型(1):
object(对象)
typeof undefined // 'undefined'
typeof null // 'object'
typeof {} // 'object'
typeof [] // 'object'
typeof new Date() // 'object'
typeof Symbol() // 'symbol'
typeof 123n // 'bigint'
function foo() {}
typeof foo // 'function'
ps: function实际上是 `object` 的一个"子类型"
js变量是弱类型
一个变量可以现在被赋值为字符串类型,随后又被赋值为数字类型。
typeof
一个用来检测给定变量的数据类型的操作符
typeof不能判断对象具体是哪种类型,一般通过Object.prototype.toString(...)或instanceof来查看。
Object.prototype.toString.call(new Date); // "[object Date]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(/reg/ig); // "[object RegExp]"
[] instanceof Array; // true
[] instanceof Object; // true
[] instanceof RegExp; // false
new Date instanceof Date; // true
typeof原理
不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位存储其类型信息。
- 000: 对象
- 010: 浮点数
- 100:字符串
- 110: 布尔
- 1: 整数
typeof null 为"object", 原因是因为 不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位都为0的话会被判断为Object类型,null的二进制表示全为0,自然前三位也是0,所以执行typeof时会返回"object"。 一个不恰当的例子,假设所有的Javascript对象都是16位的,也就是有16个0或1组成的序列,猜想如下:
Array: 1000100010001000
null: 0000000000000000
typeof [] // "object"
typeof null // "object"
因为Array和null的前三位都是000。为什么Array的前三位不是100?因为二进制中的“前”一般代表低位, 比如二进制00000011对应十进制数是3,它的前三位是011。
instanceof原理
检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
或者
查看对象B的prototype指向的对象是否在对象A的[[prototype]]链上。如果在,则返回true,如果不在则返回false。不过有一个特殊的情况,当对象B的prototype为null将会报错(类似于空指针异常)。
function _instanceof(A, B) {
var O = B.prototype;// 取B的显示原型
A = A.__proto__;// 取A的隐式原型
while (true) {
//Object.prototype.__proto__ === null
if (A === null)
return false;
if (O === A)// 这里重点:当 O 严格等于 A 时,返回 true
return true;
A = A.__proto__;
}
}
注意,instanceof运算符只能用于对象,不适用原始类型的值。 作用:
- 判断某个对象是不是另一个对象的实例 或者 用来比较一个对象是否为某一个构造函数的实例;
var Person = function() {};
var student = new Person();
console.log(student instanceof Person); // true
- 也可以判断一个实例是否是其父类型或者祖先类型的实例。
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);
console.log(auto instanceof Car);
// expected output: true
console.log(auto instanceof Object);
// expected output: true
function Person() {};
function Student() {};
var p = new Person();
Student.prototype=p; //继承原型
var s = new Student();
console.log(s instanceof Student); //true
console.log(s instanceof Person); //true
原型链
如果在对象上没有找到需要的属性或者方法引用,引擎就会继续在 [[ptototype]]关联的对象上进行查找,同理,如果在后者中也没有找到需要的引用就会继续查找它的[[prototype]],以此类推。这一系列对象的链接被称为“原型链”。
Object.ptototype是js原型链的最顶端,它的__proto__是null。
function Foo() {};
const a = new Foo();
a.__proto__ === Foo.prototype; // true
function Foo() {};
console.log(Object instanceof Object); // true
console.log(Function instanceof Function); // true
console.log(Function instanceof Object); // true
console.log(Foo instanceof Foo); // false
console.log(Foo instanceof Object); // true
console.log(Foo instanceof Function); // true