详解javascrpit中类型判断的各种方法

晨枫阳 2024-08-18 11:03:02 阅读 50

1、typeof

<code>console.log(typeof(124))//number

console.log(typeof('123'))//string

console.log(typeof(true))//boolean

console.log(typeof(undefined))//undefined

console.log(typeof(function(){}))//function

console.log(typeof(null))//object

console.log(typeof({}))//object

console.log(typeof([]))//object

console.log(typeof(new Date()))//object

操作实例

typeof函数返回的是字符串,判断代码如下

var kkk = 1234

if(typeof(kkk) == 'number'){

console.log('这个kkk是number类型')

//输出这个kkk是number类型

}

结论:typeof只能判断基本数据类型、undefined和function,复杂的数据类型以及null判断出来全是object

所以可以用typeof判断:

基本数据表类型,number、string、bool判断undefined判断function

2、Constructor

Constructor代表的是创建对象实例的构造函数,返回的是构造函数

console.log(undefined.constructor)//报错

console.log(null.constructor)//报错

let num = 123

console.log(num.constructor)//ƒ Number() { [native code] }

console.log('123'.constructor)//ƒ String() { [native code] }

console.log(true.constructor)//ƒ Boolean() { [native code] }

console.log({}.constructor)//ƒ Object() { [native code] }

console.log([].constructor)// Array() { [native code] }

console.log((new Date()).constructor)// Date() { [native code] }

console.log((function(){}).constructor)//ƒ Function() { [native code] }

操作实例

constructor函数返回的是构造函数,判断代码如下

function Person(name) {

this.name = name;

}

const person1 = new Person('Alice');

if (person1.constructor === Person) {

console.log('person1 是一个 Person 实例');

} else {

console.log('person1 不是一个 Person 实例');

}

// 对于内置对象,如Array

const arr = [1, 2, 3];

if (arr.constructor === Array) {

console.log('arr 是一个数组');

} else {

console.log('arr 不是一个数组');

}

结论

undefined和null没有构造函数,所以执行undefined.constructor报错可以用constructor来判断除了undefined和null的数据

注意事项

原型链被修改:如果对象的原型链被修改或构造函数被替换,constructor属性可能不再指向原始构造函数。继承:在涉及继承的情况下,即使子类实例的constructor属性指向子类构造函数,有时你可能还需要检查其原型链上的其他构造函数。null 和 undefined:null和undefined没有constructor属性,尝试访问它们会导致错误。

举例子说明:

(1)继承的情况

function Parent() {}

function Child() {}

// 错误地继承,没有设置Child.prototype.constructor

Child.prototype = new Parent();

const childInstance = new Child();

console.log(childInstance.constructor === Child); // false,因为Child.prototype.constructor没有被正确设置

console.log(childInstance.constructor === Parent); // true,但这不是我们想要的

// Object.create方法将原型式继承的概念规范化

/*

这个是 Object.create的实现逻辑

function create(proto) {

function F(){}

F.prototype = proto

return new F()

}

*/

// 正确的继承方式

Child.prototype = Object.create(Parent.prototype);

Child.prototype.constructor = Child; // 显式设置constructor

const anotherChildInstance = new Child();

console.log(anotherChildInstance.constructor === Child); // true,正确

(2)原型链被修改或被覆盖的情况

function Person(name) {

this.name = name;

}

const person = new Person('Alice');

console.log(person.constructor === Person); // true,初始状态

// 修改原型链

Person.prototype = {

greet: function() {

console.log(`Hello, my name is ${this.name}`);

}

};

// 注意:这里没有显式地设置constructor属性

console.log(person.constructor === Person); // false,因为Person.prototype的constructor属性可能被重置或丢失

// 如果我们想要保留constructor属性,需要在修改原型时显式设置它

Person.prototype.constructor = Person;

console.log(person.constructor === Person); // true,现在正确了

// 创建一个新的Person实例来验证

const newPerson = new Person('Bob');

console.log(newPerson.constructor === Person); // true,对于新实例,constructor属性指向正确的构造函数

上面讲解了两种类型判断的方法:一种是typeof,另一种是constructor,但是两种方法都有自己的局限性,为了更可靠地判断对象的类型,JavaScript 提供了instanceof操作符和Object.prototype.toString.call()方法,下面我们继续讲解这两种方法

3、instanceof:instanceof操作符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上

if (person1 instanceof Person) {

console.log('person1 是 Person 的实例');

}

if (arr instanceof Array) {

console.log('arr 是 Array 的实例');

}

注意事项

instanceof 不能用于基本数据类型(如 Number、String、Boolean、Undefined、Null 和 Symbol),因为这些基本数据类型在 JavaScript 中并不是对象。当你尝试对一个基本数据类型使用 instanceof 时,JavaScript 会先尝试将该基本数据类型转换为对象(例如,通过调用 Number()、String() 等函数),但即便如此,由于基本数据类型的“包装”对象(如 Number 对象的实例)与直接通过字面量创建的基本数据类型值在 instanceof 检查时并不等同,因此这样的检查总是返回 false。

console.log(1 instanceof Number); // false

console.log("hello" instanceof String); // false

console.log(true instanceof Boolean); // false

console.log(undefined instanceof Object); // false

console.log(null instanceof Object); // false

console.log(Symbol('a') instanceof Symbol); // TypeError: Right-hand side of 'instanceof' is not callable

最后一个例子中,Symbol 不是一个构造函数,不能直接用于 instanceof,因此会抛出一个 TypeError。

对于基本数据类型的检查,通常使用 typeof 运算符,它可以直接返回基本数据类型的字符串表示。对于 null 和 Array、Date 等特殊对象类型,可能需要结合使用 typeof 和 instanceof 或其他方法(如 Array.isArray())来进行准确的判断。

4、Object.prototype.toString.call():这个方法返回表示该对象的字符串,其格式遵循[object Type],其中Type是对象的类型。

console.log(Object.prototype.toString.call(undefined))//[object Undefined]

console.log(Object.prototype.toString.call(null))//[object Null]

console.log(Object.prototype.toString.call(123))//[object Number]

console.log(Object.prototype.toString.call('123'))//[object String]

console.log(Object.prototype.toString.call(true))//[object Boolean]

console.log(Object.prototype.toString.call({}))//[object Object]

console.log(Object.prototype.toString.call([]))//[object Array]

console.log(Object.prototype.toString.call(new Date()))//[object Date]

console.log(Object.prototype.toString.call(function(){}))//[objectFunction]

console.log(Object.prototype.toString.call(person1)); // [object Object]

console.log(Object.prototype.toString.call(arr)); // [object Array]

function getType(obj) {

return Object.prototype.toString.call(obj).slice(8, -1);

}

console.log(getType(person1)); // "Object"(对于普通对象,除非重写了toString方法)

console.log(getType(arr)); // "Array"

请注意,对于自定义对象,Object.prototype.toString.call()返回的通常是[object Object],除非对象的toString方法被重写以返回不同的值。在大多数情况下,instanceof和Object.prototype.toString.call()是更可靠和灵活的类型检测方法。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。