您的位置:首页技术文章
文章详情页

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

【字号: 日期:2022-06-12 16:59:45浏览:3作者:猪猪
目录typeofinstanceof 的内部实现原理Object.prototype.toString()[[class]]总结typeof

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

类型typeof 结果基本类型undefinedundefinedBooleanbooleanNumbernumberStringstringSymbolsymbolBigIntbigintnullobject引用类型Object(Object, Array, Map, Set, Regexp, Date 等)objectFunctionfunction

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

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

var arr = [];arr instanceof Array; // truetypeof arr; // 'object'function A() {}function B() {}// Javascript 继承B.prototype = new A();var b = new B();b instanceof A; // trueb instanceof B; // trueinstanceof 的内部实现原理思路:

利用 原型和原型链, 每一个函数都有一个显式的 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()toString() 方法返回一个表示该对象的字符串。该方法旨在重写(自定义)派生类对象的类型转换的逻辑。valueOf() 方法返回对象的原始值表示

该方法由 字符串转换优先调用, 但是 数字的强制转换和原始值的强制转换 会优先调用 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([])); // trueisDate(new Date()); // trueisRegExp(/\w/); // trueisFunction(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' ==> 123let 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(); },};总结当一侧为 String 类型,被识别为字符串拼接,并会优先将另一侧转换为字符串类型。当一侧为 Number 类型,另一侧为原始类型,则将原始类型转换为 Number 类型。当一侧为 Number 类型,另一侧为引用类型,将引用类型和 Number 类型转换成字符串后拼接。只有 null undefined '' NaN 0 false 这几个是 false,其他的情况都是 true,比如 {} , []。

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

标签: JavaScript