<!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>
</body>
</html>
<script>
/*
数据类型检测
1.typeof用来检测数据类型的运算符
typeof [value] => 字符串,包含对应的数据类型
局限性:
typeof null -> "object"
typeof 检测对象类型值,除了可执行对象{函数}可以检测出来是"function",其余都是"object"
基于typeof检测一个未声明的变量,结果是"undefined",而不会报错「基于let在后面声明则会报错」
typeof 检测原始值对应的对象类型的值,结果是字符串"object"
为啥:typeof检测数据类型是,按照计算机底层存储的二进制值,来进行检测的,它认为以"000"开头的都是对象,而null都是零
好处:
简单、性能好
2. instanceof临时用来"拉壮丁"检测数据类型,本意是检测当前实例是否属于这个类
[value] instanceof [Ctor] => true/false
好处: 细分对象数据类型值「但是不能因为结果是true就说它是标准普通对象』
弊端:不能检测原始值类型的值『但是原始值对应的对象格式实例则可以检测』;但是因为原型链指向是可以肆意改动的,所以最后检测的结果不一定准确;
原理:按照原型链检测的;只有当前检测的构造函数(它的原型对象),出现在实例的原型链上,则检测结果就是TRUE;如果找到Object.prototype都没有找到,则结果就是FALSE;
f instanceof Fn -> Fn[Symbol.hasInstance](f) 新语法规范
3.constructor 也是"拉壮丁"
constructor的修改比instanceof更"肆无忌惮"
4.Object.prototype.toString.call([value]) 这是JS中唯一一个检测数据类型吗没有任何瑕疵的『最准确的,除了性能比typepf略微少那么一丢丢,写起来略微麻烦一点点』
=>"[object Number/String/Boolean/Null/Undefined/Symbol/BigInt/object/Function/RegExp/Array/Math/GeneratorFunction... (原型是什么类型检测出来是什么 object后面就跟什么)]"
大部分内置类的原型上都有toString方法,一般都是转换为字符串的,但是Object.prototype.toString是检测数据类型的,返回值中包含自己所属的构造函数的信息...
Object.prototype.toString.call([value])
1.为啥要用call?
([]).toString 调用的是Array.prototype上的toString,是转换为字符串
({}).toString 调用的是Object.prototype上的toString,是检测数据类型的『方法中的this是谁,就是检测谁的类型』 —> 我们需要把Object.prototype.toString执行,而且还要改变其中的this
->({}).toString.call(10) =>"[object Number]"
2.检测返回值遵循啥原则?
一般都是返回当前实例所属的构造函数类型信息
但是如果实例对象拥有 Math[Symbol.toStringTag]="Math"=> Object.prototype.toString.call(Math)=> "[object Math]"
*/
// 4.Object.prototype.toString.call([value])
/* class Fn{
// constructor(){
// this[Symbol.toStringTag]="Fn"
// }
[Symbol.toStringTag]="Fn";
}
let f =new Fn;
console.log(Object.prototype.toString.call([Fn]));//"[object Function]"
console.log(Object.prototype.toString.call([f]));//"[object object]" ? */
// GeneratorFunction 生成器函数
/* // 3.constructor
let arr=[],n=10,m=new Number(10);
console.log(arr.constructor===Array);//=>true
console.log(arr.constructor===RegExp);//=>false
console.log(arr.constructor===Object);//=>false
// 如果CTOR结果和Object相等,说明可能是标准普通对象
console.log(n.constructor===Number);//=>true
console.log(m.constructor===Number);//=>true
/* function Fn(){}
let f =new Fn;
console.log(f.constructor===Fn);//=>true
console.log(f.constructor===Object);//=>false */
/*function Fn(){}
Fn.prototype={};//重新定向后丢失了constructor
let f =new Fn;
console.log(f.constructor===Fn);//=>fale
console.log(f.constructor===Object);//=>ture */
// 2.instanceof
/* let arr=[10,20,30];
console.log(arr instanceof Array);//=>true
console.log(arr instanceof RegExp);//=>false
console.log(arr instanceof Object);//=>true
console.log(new Number(1) instanceof Number);//=>true
console.log(1 instanceof Number);//=>false */
/* // class Fn{
// }
// Fn.prototype=Array.prototype;//不行没有用
// let f=new Fn;
// function Fn() {
// }
// Fn.prototype = Array.prototype;
// let f = new Fn;
// console.log(f instanceof Array); */
/* // function Fn() { }
// Fn[Symbol.hasInstance](f)=function (){}//手动加一个 普通构造函数,它的Symbol.hasInstance属性无法被直接修改的,但是ES6语法中可以!!
class Fn{//新语法重写可以修改
static[Symbol.hasInstance](){
console.log('OK');
if(Array.isArray(obj)) return true;
return false;
}
}
let f = new Fn;
let arr=[10,20,30]
console.log(f instanceof Fn);//=>true
console.log(arr instanceof Fn);//=>true
// console.log(Fn[Symbol.hasInstance](f));//=>true */
/* // 自己重写 instanceof方法 我们这个方法支持原始值类型
const instance_of = function instance_of(obj, Ctor) {
if (Ctor === null) throw new TypeError('Right-hand side of intanceof is not an object');
let type = typeof Ctor;
if (!/^object|function)$/i.test(type)) throw new TypeError('Right-hand side of intanceof is not an object');
if (!/^function)$/i.test(type)) throw new TypeError('Right-hand side of intanceof is not an object');
if (!Ctor.prototype) throw new TypeError('Function has non-object prototype in instanceof check');
let proto = Object.getPrototypeOf(obj);
while (proto) {
if (proto === Ctor.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
return false;
};
console.log(instance_of([], Array));//=>true
console.log(instance_of([], RegExp));//=>false
console.log(instance_of(1, Number));//=>true 浏览器默认进行装箱操作 直接检测原型
console.log(instance_of(Symbol(), Symbol));//=>true
console.log(instance_of([], {}));//=>false 但是 instanceof 原本检查会报错 因为右侧不是一个函数(并且必须是函数是个对象有原型[箭头函数会报错(没有原型)]) */
</script>
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)