摘要:复杂类型复杂类型从字面量是直接生成构造函数的,所以不会像基本类型一样两种情况。
JS(ES6)中的基本数据类型:1.数值型(Number):包括整数、浮点数、2.布尔型(Boolean)、3.字符串型(String)、4.数组(Array)、5.空值(Null) 、6.未定义(Undefined),基本数据类型是按值访问的,因为可以直接操作保存在变量中的实际值。1.typeof
引用类型:Object 、Array 、Function 、Data,引用数据类型是保存在堆内存中的对象
var a; console.log("1:" + typeof a); var b = null; console.log("2:" + typeof b); var c = undefined; console.log("3:" + typeof c); var d = new Object; console.log("4:" + typeof d); var e = function() {}; console.log("5:" + typeof e); var f = {}; console.log("6:" + typeof f); var g = ""; console.log("7:" + typeof g); var h = []; console.log("8:" + typeof h); var i = true; console.log("9:" + typeof i); var j = 123; console.log("10:" + typeof j); var k = NaN; console.log("11:" + typeof k); var l = /^[-+]?d+$/; console.log("12:" + typeof l);
打印结果如下
总结:typeof对null、undefined、NaN、数组、正则、Object的类型都为object
2.constructorconstructor 用于判断一个变量的原型,constructor 属性返回对创建此对象的数组函数的引用.
当一个函数 F被定义时,JS引擎会为F添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向 F 的引用,当执行 var f = new F() 时,F 被当成了构造函数,f 是F的实例对象,此时 F 原型上的 constructor 传递到了 f 上,因此 f.constructor === F
var F = function(){} console.log(F.prototype); var f = new F(); console.log(f.constructor===F) //true
不难看出,F 利用原型对象上的 constructor 引用了自身,当 F 作为构造函数来创建对象时,原型上的 constructor 就被遗传到了新创建的对象上, 从原型链角度讲,构造函数 F 就是新对象的类型。这样做的意义是,让新对象在诞生以后,就具有可追溯的数据类型,也就是说对象的constructor属性指向他的构造函数
所以内置对象在内部构建时阔以这样做出判断
注:
null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断
constructor属性并非一定指向构造函数,他也是可以修改、变更的(当把F.prototype = {}改写后,会默认把constructor覆盖掉)
instanceofinstanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性
及的构造函数有这些基础类型:String、Number、Boolean、Undefined、Null、Symbol(ES6引入了一种新的原始数据类型Symbol,表示独一无二的值); 复杂类型:Array,Object; 其他类型:Function、RegExp、Date。
var obj = new Object() obj instanceof Object // true
注意左侧必须是对象(object),如果不是,直接返回false,列如:
var num = 1 num instanceof Number // false num = new Number(1) num instanceof Number // true
可以看出都是num,而且都是1,只是因为第一个不是对象,是基本类型,所以直接返回false,而第二个是封装成对象,所以true。
这里要严格注意这个问题,有些说法是检测目标的__proto__与构造函数的prototype相同即返回true,这是不严谨的,检测的一定要是对象才行,如:
基础类型
var num = 1 num.__proto__ === Number.prototype // true num instanceof Number // false num = new Number(1) num.__proto__ === Number.prototype // true num instanceof Number // true num.__proto__ === (new Number(1)).__proto__ // true
上面例子可以看出,1与new Number(1)几乎是一样的,只是区别在于是否封装成对象,所以instanceof的结果是不同的,string、boolean等,这些基础类型一样的。
new String(1) // String {"1"} String(1) // "1"
new String(1)与String(1)是不同的,new是封装成对象,而没有new的只是基础类型转换,还是基础类型
其他基础类型一样的。
复杂类型,比如数组与对象,甚至函数等,与基础类型不同。
复杂类型
var arr = [] arr instanceof Array // true arr instanceof Object // true Array.isArray(arr) // true
复杂类型从字面量是直接生成构造函数的,所以不会像基本类型一样两种情况。
但是上面那个问题,当然,基础类型也会有这个问题,就是与Object对比。没办法,Object在原型链的上层,所以都会返回true,如下:
(new Number(1)) instanceof Object // true
由于从下往上,比如你判断是Number,那就没必要判断是不是Object了,因为已经是Number了……
其他类型
var reg = new RegExp(//) reg instanceof RegExp // true reg instanceof Object // true var date = new Date() date instanceof Date // true date instanceof Object // true 除了Function,都一样,具体Function如下: function A() {} var a = new A() a instanceof Function // false a instanceof Object // true A instanceof Function // true
这里要注意,function A() {}相当于var A; A = function() {},然后分析:
a是new出来,所以是经过构造,因此已经是对象,不再是函数,所以false
a是经过构造的对象,返回ture没问题
A是个函数,这没什么问题
{}.toString.call(obj)用法如下
console.log({}.toString.call(1)); console.log({}.toString.call("11")); console.log({}.toString.call(/123/)); console.log({}.toString.call({})); console.log({}.toString.call(function() {})); console.log({}.toString.call([])); console.log({}.toString.call(true)); console.log({}.toString.call(new Date())); console.log({}.toString.call(new Error())); console.log({}.toString.call(null)); console.log({}.toString.call(undefined)); console.log(String(null)); console.log(String(undefined));
返回如下
注意:必须通过 call 或 apply 来调用,而不能直接调用 toString , 从原型链的角度讲,所有对象的原型链最终都指向了 Object, 按照JS变量查找规则,其他对象应该也可以直接访问到 Object 的 toString方法,而事实上,大部分的对象都实现了自身的 toString 方法,这样就可能会导致 Object 的 toString 被终止查找,因此要用 call/apply 来强制调用Object 的 toString 方法
jQuery中的方法$.type(),就是用到了toString
type: function( obj ) { if ( obj == null ) { return obj + ""; } // Support: Android<4.0, iOS<6 (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call(obj) ] || "object" : typeof obj; },
分析源代码:
typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call(obj) ]
通过判断传入类型,如果是object或者function类型就直接返回class2type 中键值是对的结果,如果不是,那么一定就是基本类型, 通过 typeof 就可以
class2type[ toString.call(obj) ] || "object"
这是为了防止一些未知情况的,如果未取到,就返回object,保证了程序可用性
参考文章:
JS类型判断,typeof/constructor/instanceof的区别
js中的constructor和prototype
JS类型判断
jquery源码
揭开js之constructor属性的神秘面纱
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/100670.html
摘要:专题系列共计篇,主要研究日常开发中一些功能点的实现,比如防抖节流去重类型判断拷贝最值扁平柯里递归乱序排序等,特点是研究专题之函数组合专题系列第十六篇,讲解函数组合,并且使用柯里化和函数组合实现模式需求我们需要写一个函数,输入,返回。 JavaScript 专题之从零实现 jQuery 的 extend JavaScritp 专题系列第七篇,讲解如何从零实现一个 jQuery 的 ext...
摘要:注意基本变量类型不是对象类型,只有基本包装类型才是对象类型。至于显示的原型,在里用属性表示,这个是原型继承的基础知识,在这里就不在叙述了。 前言 如果你要开发一个复杂的产品,那么肯定少不了使用面向对象机制,当然也避不开 Javascript 里面的继承,instanceof 运算符是原生 Javascript 语言中用来判断实例继承的操作符。所以我们有必要深入理解该运算符! inst...
摘要:本文将讲解我目前所知道的判断数据类型的方法。数据类型一共有种除了之外的种属于原始数据类型。等价于问题四的返回值是什么答案。 本文将讲解我目前所知道的判断JavaScript数据类型的方法。JavaScript数据类型一共有7种: Undefined Null Boolean String Symbol Number Object 除了Object之外的6种属于原始数据类型。有时,我...
摘要:除和外,所有的数据类型都是可以转化为对象,而如果是对象,就肯定有构造函数。特性因为和没有构造函数,因此不能用此方法来判断。由于同一条原型继承链上的各个对象的构造函数都不一样,因此,此方法可以区分开继承链上的各个自定义数据类型。 typeof 用法示例 var arr = []; typeof arr; //object typeof(arr); //object typeo...
摘要:对象类型常见的有,,,正则新增自己提供的乐行判断如果不对对象做严格区分使用。的实现使用了原型继承的表示左表达式,表示右表达式,它是用是否等于来判断对象的类型的。常见框架和库的实数据类型判断测试这里将的实现原理抽取出来,用原生实现。 JavaScript一共有六种数据类型,分为原始类型(又名基本类型)和对象类型(又名引用类型) 原始类型有五种,分别为number,string,boole...
摘要:比如我们今天要讨论的,在当中如何判断一个数组是数组。在数组的原型链上也能找到构造函数由上面的几行代码可以看出,使用运算符可以分辨数组和对象,可以判断数组是数组。用判断实例化的数组拥有一个属性,这个属性指向生成这个数组的方法。 如果你没有注意过这个问题,那么这个标题应该会让你感到困惑,判断数据类型这么基础的问题能有什么坑呢? 少年,你不能太天真了,我们朝夕面对的这门语言,可是JavaSc...
阅读 1471·2021-11-24 09:38
阅读 3350·2021-11-18 10:02
阅读 3229·2021-09-22 15:29
阅读 2919·2021-09-22 15:15
阅读 1006·2021-09-13 10:25
阅读 1800·2021-08-17 10:13
阅读 1919·2021-08-04 11:13
阅读 1958·2019-08-30 15:54