0 / JS中创立值的两种形式
JS 中创立一个值有两种计划:① 字面量形式 ② 构造函数形式
留神:构造函数形式
① 不能 new Symbol/new BigInt
② 能够Object(symbol)/Object(bigint)
其余数据类型值也能够,然而排除null/undefined
//=> 字面量形式
let n = 100;
let obj = {};
//=> 构造函数形式
let m = new Number(100);
let obj2 = new Object();
△ 创立值的两种形式
对于根本数据类型,两种创立形式后果是不一样的:
① 字面量形式失去的是根本数据类型,即:非凡的实例
② 而构造函数形式失去的是对象数据类型,即:正规的实例
对于援用数据类型,两种创立形式后果:除了语法上的区别,实质上是没有区别的,获取的都是对应类的实例对象
1 / JS中数据类型检测
JS中数据类型检测:
① typeof value;
简略不便
② Object.prototype.toString.call(value)
万全之策
③ prop instanceof constructor
长期当“壮丁”
④ constructor
长期当“壮丁”
2 / typeof
△ 图1_typeof 判断数据类型
typeof 检测数据类型:
1、 能够无效的检测出大部分的数据类型
2、 typeof null
检测的后果是object
JS设计的如此:数据值都是依照二进制存储的
1整数,010浮点数,100字符串,110布尔,000对象,-2^30undefined,000000null…………
即:typeof 检测数据类型时,依照二进制存储的值检测的,把null认为是对象了
3、 typeof 不会细分具体的对象数据类型值,所有的对象数据类型值,检测进去都是"object"
4、 typeof 检测基于构造函数创立进去的,根本数据类型的实例对象,后果也是"object"
△ 图2_基于构造函数创立进去的根本数据类型的实例对象
3 / Object.prototype.toString.call()
Object.prototype.toString.call() 检测每个对象的类型
1、大部分内置类的原型上都有toString办法,但个别都是转为字符串,只有Object.prototype上的toString办法应用来返回以后实例对象所属的信息
"[object 所属的构造函数信息]"
2、所属的构造函数信息:是依据Symbol.toStringTag
来获取的,【有,是依据它;没有,是浏览器本人计算的】
var toString = Object.prototype.toString;
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
△ Object.prototype.toString
var class2type = {};
var toString = class2type.toString;
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
△ ({}).toString
function* fn() {}
console.log(Object.prototype.toString.call(fn)); //->"[object GeneratorFunction]"
△ 结构器函数
function Fn() {}
Fn.prototype[Symbol.toStringTag] = 'Miao~';
let f = new Fn;
console.log(Object.prototype.toString.call(f)); //=>"[object Miao~]"
△ 自定义类,指定toStringTag的值
4 / instanceof
instanceof 运算符检测构造函数的prototype属性是否呈现在某个实例对象的原型链上
∴ 基于instanceof能够细分不同类型的对象,也能够检测基于构造函数形式创立的根本数据类型对象的值
然而,长期拉来当“壮丁”,有一些注意事项:
1、检测原理:构造函数[Symbol.hasInstance](实例)
2、检测原理:检测以后构造函数的原型prototype是否呈现在以后实例所处的原型链上\__proto__,即:只有能呈现后果就为true
3、在JS中原型链是能够手动改的,检测后果不精确
4、所有的实例的原型链最初都指向了Object.prototype
,即:实例 instanceof Object
后果都会为true
5、字面量形式创立的根本数据类型值是无奈基于instanceof检测的(浏览器不会把它转为new的形式),即:字面量创立的根本数据类型值不是对象,不存在\__proto__这个货色
6、…………
var n = 100;
var m = new Number(1000);
console.log(n instanceof Number); //=> false
console.log(m instanceof Number); //=> true
console.log(m instanceof Object); //=> true
var arr = [1,2,3];
var obj = {name:'晚霞的光影笔记', id:'zhaoxiajingjing'};
console.log(arr instanceof Array); //=> true
console.log(obj instanceof Object); //=> true
console.log(arr instanceof Object); //=> true
△ 字面量和构造函数创立值
class Fn {
static[Symbol.hasInstance](){
console.log('miao~');
return false;
}
}
let f = new Fn;
console.log(f instanceof Fn);
//=>输入后果:
// miao~
// false
△ 调用:构造函数的Symbol.hasInstance
function Fn(){}
Fn.prototype = Array.prototype;
let f = new Fn;
console.log(f instanceof Array); //=> true
△ 手动批改原型指向
5 / constructor
constructor结构器,被拉来检测数据类型,也是长期抓来的“壮丁”
它的问题:能够手动被批改掉
var n = 100;
var m = new Number(1000);
console.log(n.constructor === Number); //=> true
console.log(m.constructor === Number); //=> true
var arr = [1,2,3];
var obj = {name:'晚霞的光影笔记', id:'zhaoxiajingjing'};
console.log(arr.constructor=== Array); //=> true
console.log(obj.constructor === Object); //=> true
console.log(arr.constructor === Object); //=> false
△ 通过constructor检测
function Fn(){}
Fn.prototype = {
constructor:Array
};
let f = new Fn;
console.log(f.constructor === Fn); //=> false
console.log(f.constructor === Array); //=> true
△ 能够手动批改constructor指向
6 / 小结
JS中检测数据类型的形式4种:
1、typeof,无奈辨别对象数据类型值
2、Object.prototype.toString,万全之策,次要检测Symbol.toStringTag的值,没有就按浏览器计算的
3、instanceof,“壮丁”
① 检测原理:构造函数[Symbol.hasInstance]()
② 检测构造函数的prototype原型是否呈现在实例对象的原型链上
=> JS的原型链是能够手动批改指向的
=> JS的原型也是能够手动批改的
③ 不能检测字面量创立的根本类型值
4、constructor,“壮丁” 能够进行手动批改指向
– end-
发表回复