js-类型检测
原创wg_iGBFcBFB 博主文章分类:js高级相关 ©著作权
©著作权归作者所有:来自51CTO博客作者wg_iGBFcBFB的原创作品,请联系作者获取转载授权,否则将追究法律责任
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
/* JQ中关于数据类型检测的源码 */
var getProto = Object.getPrototypeOf; //获取实例的原型对象
var class2type = {};
var toString = class2type.toString; //Object.prototype.toString 检测数据类型
var hasOwn = class2type.hasOwnProperty; //Object.prototype.hasOwnProperty
var fnToString = hasOwn.toString; //Function.prototype.toString 把函数转换字符串
var ObjectFunctionString = fnToString.call(Object); //"function Object() { [native code] }"
// 循环数据中的每一项:建立数据类型检测的映射表
// + [object Boolean]/[object Number]/[object String]都是为了处理基于”构造函数“创建的基本数据值的引用类型值,最后期许检测出来的结果依然是"boolean"/"number"/"string"
// typeof new Number(10) -> "object"
// toString.call(new Number(10)) -> "[object Number]"
[
"Boolean",
"Number",
"String",
"Symbol",
"Function",
"Array",
"Date",
"RegExp",
"Object",
"Error",
"GeneratorFunction"
].forEach(function (name) {
class2type["[object " + name + "]"] = name.toLowerCase();
});
// 检测数据类型的公共方法
function toType(obj) {
// null/undefined
if (obj == null) {
return obj + "";
}
// 如果是引用数据类型(包含:new Number(10)这种),则基于Object.prototype.toString来检测(拿检测的结果到之前建立的映射表中去匹配查找,找到对象的小写数据类型);而基本数据类型,之前排除了null/undefined,剩下的基于typeof即可解决!
return typeof obj === "object" || typeof obj === "function" ?
class2type[toString.call(obj)] || "object" :
typeof obj;
}
// console.log(toType('obj')); // string
// console.log(toType(1123)); // number
// console.log(toType({1:2})); // object
// console.log(toType([1,3])); // array
// console.log(toType(function(){})); // function
// console.log(toType(null)); // null
// console.log(toType(undefined)); // undefined
// console.log(toType(true)); // boolean
// 检测是否为一个函数
var isFunction = function isFunction(obj) {
// Support: Chrome <=57, Firefox <=52
// In some browsers, typeof returns "function" for HTML <object> elements
// (i.e., `typeof document.createElement( "object" ) === "function"`).
// We don't want to classify *any* DOM node as a function.
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
// 检测是否为window
var isWindow = function isWindow(obj) {
// window.window===window 所有符合这个特点的对象就是浏览器的window对象
// null/undefined无法进行成员访问
return obj != null && obj === obj.window;
};
// 检测是否为数组或者类数组
function isArrayLike(obj) {
// length:要不然是false(不存在或者没有length属性),要不然是length的属性值
// type:检测出来的数据类型
var length = !!obj && "length" in obj && obj.length,
type = toType(obj);
// 如果是函数或者window直接返回false,因为:函数或者window也都有length属性
if (isFunction(obj) || isWindow(obj)) {
return false;
}
// type === "array" -> 数组
// length === 0 -> 有length属性,值是零「空的类数组」
// typeof length === "number" && length > 0 -> length属性值大于零(非空类数组)
// (length - 1) in obj -> 最大索引也存在,我们认为其是按照索引递增的(不一定准确)
return type === "array" || length === 0 ||
typeof length === "number" && length > 0 && (length - 1) in obj;
}
// 检测是否为一个纯粹的对象 => {} 数组对象/正则对象等都不算
function isPlainObject(obj) {
var proto,
Ctor,
type = toType(obj);
// 不存在或者检测数据类型的结果都不是object,那么一定不是纯粹的对象
if (!obj || type !== "object") {
return false;
}
// 不存在原型的情况:Object.create(null)
proto = getProto(obj);
if (!proto) {
return true;
}
// 获取当前值原型对象上的constructor「获取它的构造函数」
Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
// 有构造函数,并且构造函数需要直接是Object才可以:排除了NodeList/自定类的实例等内容,只有它的原型直接是Object.prototype的才可以 => ObjectFunctionString===fnToString.call(Object)
return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
}
// 检测是否为一个空对象
// function isEmptyObject(obj) {
// var name;
// // for in遍历的时候,可以遍历到自己在内置类原型上扩展的方法
// // 并且它无法遍历Symbol的属性值
// for (name in obj) {
// return false;
// }
// return true;
// }
// Object.prototype.AA = 100;
// let obj = {};
// console.log(isEmptyObject(obj)); //false
// let obj = {
// [Symbol()]: 100
// };
// console.log(isEmptyObject(obj)); //true
function isEmptyObject(obj) {
var keys = [
...Object.getOwnPropertyNames(obj),
...Object.getOwnPropertySymbols(obj)
];
return keys.length === 0;
}
Object.prototype.AA = 100;
let obj = {};
console.log(isEmptyObject(obj)); //true
obj = {
[Symbol()]: 100
};
console.log(isEmptyObject(obj)); //false
</script>
</body>
</html>
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
JS-检测浏览器类型及版本
原址:http://www.jb51.net/article/50464.htm 我在原基础上添加了谷歌的判断,但只有ie的有版本的判断。不过这些就够了。
Javascript 方法汇总 safari chrome firefox -
JS- this
其实,this的取值,分四种情况。我们来挨个看一下。在此再强调一遍一个非常重要的知识点:在函数中this到底取何值
JS this 函数 构造函数 jquery -
JS-入门
作用:其实也就是JAVAscript漏洞BEEF中hook.js是一个钩子-木马学习路线:正式学习JavaScript输出使用 window.alert() 弹出警告框。使用 document.write()
javascript html5 html 字符串 数组 -
JS-函数
JS-函数
函数 JS 闭包 -
JS-面向对象
话说,再次看完这个实例后的我,开始怀疑面向对象和JSON的区别。。。并开始怀疑这是面向对象的真实性
Javascript 学习笔记 案例实现 html 面向对象 -
js-惰性函数js
-
JS-语法
1、全等于 2、不等于 !==
html 其他 -
mysql8双主复制故障恢复
1 主从异步复制1.1 架构介绍 1. master将改变记录到二进制日志( binary log) 2. slave将master的binary log拷贝到它的中继日志(relay log) 3. sl
mysql8双主复制故障恢复 mysql 主从复制 客户端