JavaScript

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > js类型判断内部原理

js类型判断内部实现原理示例详解

作者:。。。嗯

这篇文章主要为大家介绍了js类型判断内部实现原理示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

typeof

typeof 操作符唯一的目的就是检查数据类型

类型typeof 结果
基本类型undefinedundefined
Booleanboolean
Numbernumber
Stringstring
Symbolsymbol
BigIntbigint
nullobject
引用类型Object(Object, Array, Map, Set, Regexp, Date 等)object
Functionfunction

你会发现用typeof来判断引用类型时, 都会返回 'object'. 为此, 引入了 instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

var arr = [];
arr instanceof Array; // true
typeof arr; // "object"
function A() {}
function B() {}
// Javascript 继承
B.prototype = new A();
var b = new B();
b instanceof A; // true
b instanceof B; // true

instanceof 的内部实现原理

利用 原型和原型链, 每一个函数都有一个显式的 prototype, 每一个对象都有一个隐式原型 **proto**, 当我们对象的原型链中存在构造函数的显式原型 prototype时, 我们就可以确定它们之间存在关系;

function myInstanceOf(constructor, instance) {
  let prototype = constructor.prototype;
  let proto = instance.__proto__;
  while (true) {
    // 说明道原型链订单, 还未找到, 返回 false
    if (proto === null) {
      return false;
    }
    if (proto === prototype) {
      return true;
    }
    // 继续向 proto 的原型链上遍历
    proto = Object.getPrototypeOf(proto);
  }
}

Object.prototype.toString()

该方法由 字符串转换优先调用, 但是 数字的强制转换原始值的强制转换 会优先调用 valueOf, 因为基本的 valueOf() 方法返回一个对象,toString() 方法通常在结束时调用

默认情况下(不重写 toString方法), 任何一个对象调用 Object原生的 toString方法, 都会返回一个 [object type], 其中 type是对象的类型

let a = {};
a; // {}
a.toString(); // "[object Object]"

[[class]]

每个 实例 都有一个 [[Class]] 属性,这个属性中就指定了上述字符串中的 type 。 [[Class]] 不能直接地被访问,但通常可以通过 Object.prototype.toString.call(..) 方法调用来展示。

// Boolean 类型,tag 为 "Boolean"
Object.prototype.toString.call(true); // => "[object Boolean]"
// Number 类型,tag 为 "Number"
Object.prototype.toString.call(10); // => "[object Boolean]"
// String 类型,tag 为 "String"
Object.prototype.toString.call("1312312"); // => "[object String]"
// Array 类型,tag 为 "String"
Object.prototype.toString.call([]); // => "[object Array]"
// Function 类型, tag 为 "Function"
Object.prototype.toString.call(function () {}); // => "[object Function]"
// Error 类型(包含子类型),tag 为 "Error"
Object.prototype.toString.call(new Error()); // => "[object Error]"
// RegExp 类型,tag 为 "RegExp"
Object.prototype.toString.call(/\d+/); // => "[object RegExp]"
// Date 类型,tag 为 "Date"
Object.prototype.toString.call(new Date()); // => "[object Date]"
// 其他类型,tag 为 "Object"
Object.prototype.toString.call(new (class {})()); // => "[object Object]"

所以可以通过这个方法来判断每个对象的类型

function generator(type){
  return function(value){
    return Object.prototype.toString.call(value) === "[object "+ type +"]"
  }
}
let isFunction = generator('Function')
let isArray = generator('Array');
let isDate = generator('Date');
let isRegExp = generator('RegExp');
isArray([]));    // true
isDate(new Date()); // true
isRegExp(/\w/); // true
isFunction(function(){}); //true

以下是一道简单的面试题

+[1 + [2] + 3] + [1 + 2 + true - false] + [[3 - false + "1"]];
// 拆分一下
let a = +[1 + [2] + 3];
// [2]会首先进行转换 [2].valueOf, 结果不是基本类型, [2]在调用toString(), 返回'2', 最后 1 + '2' + 3, 1,3进行隐式转换, +'123' ==> 123
let b = [1 + 2 + true - false];
// [3+true-false], true, false会进行转换, true=>1, false=>0, 最后1-0==>[1+3]==>[4]==>[4].valueOf().toString()==>'4'
let c = [[3 - false + "1"]];
// 先转换数组里面的一层, [3-0+'1']==>['31'], 结果: [['31']]==>[['31']].valueOf().toString()==>'31'
// 最后 a+b+c
// 123+'4'+'31'==>123431

面试题目, 如何同时让等式成立, a===1&&a===2&&a===3

思路:

重写 a 的 valueOf 方法

let a = {
  value: [3, 2, 1],
  valueOf: function () {
    return this.value.pop();
  },
};

总结

以上就是js类型判断内部实现原理示例详解的详细内容,更多关于js类型判断内部原理的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文