翼度科技»论坛 编程开发 JavaScript 查看内容

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

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
typeof

typeof 操作符唯一的目的就是检查数据类型
类型typeof 结果基本类型undefinedundefinedBooleanbooleanNumbernumberStringstringSymbolsymbolBigIntbigintnullobject引用类型Object(Object, Array, Map, Set, Regexp, Date 等)objectFunctionfunction你会发现用typeof来判断引用类型时, 都会返回 'object'. 为此, 引入了 instanceof
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
  1. var arr = [];
  2. arr instanceof Array; // true
  3. typeof arr; // "object"
  4. function A() {}
  5. function B() {}
  6. // Javascript 继承
  7. B.prototype = new A();
  8. var b = new B();
  9. b instanceof A; // true
  10. b instanceof B; // true
复制代码
instanceof 的内部实现原理


  • 思路:
利用 原型和原型链, 每一个函数都有一个显式的 prototype, 每一个对象都有一个隐式原型 **proto**, 当我们对象的原型链中存在构造函数的显式原型 prototype时, 我们就可以确定它们之间存在关系;
  1. function myInstanceOf(constructor, instance) {
  2.   let prototype = constructor.prototype;
  3.   let proto = instance.__proto__;
  4.   while (true) {
  5.     // 说明道原型链订单, 还未找到, 返回 false
  6.     if (proto === null) {
  7.       return false;
  8.     }
  9.     if (proto === prototype) {
  10.       return true;
  11.     }
  12.     // 继续向 proto 的原型链上遍历
  13.     proto = Object.getPrototypeOf(proto);
  14.   }
  15. }
复制代码
Object.prototype.toString()


  • toString() 方法返回一个表示该对象的字符串。该方法旨在重写(自定义)派生类对象的类型转换的逻辑。
  • valueOf() 方法返回对象的原始值表示
该方法由 字符串转换优先调用, 但是 数字的强制转换原始值的强制转换 会优先调用 valueOf, 因为基本的 valueOf() 方法返回一个对象,toString() 方法通常在结束时调用
默认情况下(不重写 toString方法), 任何一个对象调用 Object原生的 toString方法, 都会返回一个 [object type], 其中 type是对象的类型
  1. let a = {};
  2. a; // {}
  3. a.toString(); // "[object Object]"
复制代码
[[class]]

每个 实例 都有一个 [[Class]] 属性,这个属性中就指定了上述字符串中的 type 。 [[Class]] 不能直接地被访问,但通常可以通过 Object.prototype.toString.call(..) 方法调用来展示。
  1. // Boolean 类型,tag 为 "Boolean"
  2. Object.prototype.toString.call(true); // => "[object Boolean]"
  3. // Number 类型,tag 为 "Number"
  4. Object.prototype.toString.call(10); // => "[object Boolean]"
  5. // String 类型,tag 为 "String"
  6. Object.prototype.toString.call("1312312"); // => "[object String]"
  7. // Array 类型,tag 为 "String"
  8. Object.prototype.toString.call([]); // => "[object Array]"
  9. // Function 类型, tag 为 "Function"
  10. Object.prototype.toString.call(function () {}); // => "[object Function]"
  11. // Error 类型(包含子类型),tag 为 "Error"
  12. Object.prototype.toString.call(new Error()); // => "[object Error]"
  13. // RegExp 类型,tag 为 "RegExp"
  14. Object.prototype.toString.call(/\d+/); // => "[object RegExp]"
  15. // Date 类型,tag 为 "Date"
  16. Object.prototype.toString.call(new Date()); // => "[object Date]"
  17. // 其他类型,tag 为 "Object"
  18. Object.prototype.toString.call(new (class {})()); // => "[object Object]"
复制代码
所以可以通过这个方法来判断每个对象的类型
  1. function generator(type){
  2.   return function(value){
  3.     return Object.prototype.toString.call(value) === "[object "+ type +"]"
  4.   }
  5. }
  6. let isFunction = generator('Function')
  7. let isArray = generator('Array');
  8. let isDate = generator('Date');
  9. let isRegExp = generator('RegExp');
  10. isArray([]));    // true
  11. isDate(new Date()); // true
  12. isRegExp(/\w/); // true
  13. isFunction(function(){}); //true
复制代码
以下是一道简单的面试题
  1. +[1 + [2] + 3] + [1 + 2 + true - false] + [[3 - false + "1"]];
  2. // 拆分一下
  3. let a = +[1 + [2] + 3];
  4. // [2]会首先进行转换 [2].valueOf, 结果不是基本类型, [2]在调用toString(), 返回'2', 最后 1 + '2' + 3, 1,3进行隐式转换, +'123' ==> 123
  5. let b = [1 + 2 + true - false];
  6. // [3+true-false], true, false会进行转换, true=>1, false=>0, 最后1-0==>[1+3]==>[4]==>[4].valueOf().toString()==>'4'
  7. let c = [[3 - false + "1"]];
  8. // 先转换数组里面的一层, [3-0+'1']==>['31'], 结果: [['31']]==>[['31']].valueOf().toString()==>'31'
  9. // 最后 a+b+c
  10. // 123+'4'+'31'==>123431
复制代码
面试题目, 如何同时让等式成立, a===1&&a===2&&a===3
思路:
重写 a 的 valueOf 方法
  1. let a = {
  2.   value: [3, 2, 1],
  3.   valueOf: function () {
  4.     return this.value.pop();
  5.   },
  6. };
复制代码
总结


  • 当一侧为 String 类型,被识别为字符串拼接,并会优先将另一侧转换为字符串类型。
  • 当一侧为 Number 类型,另一侧为原始类型,则将原始类型转换为 Number 类型。
  • 当一侧为 Number 类型,另一侧为引用类型,将引用类型和 Number 类型转换成字符串后拼接。
  • 只有 null undefined '' NaN 0 false 这几个是 false,其他的情况都是 true,比如 {} , []。
以上就是js类型判断内部实现原理示例详解的详细内容,更多关于js类型判断内部原理的资料请关注脚本之家其它相关文章!

来源:https://www.jb51.net/javascript/2920825cp.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具