我有一个需要向其传递对象的函数。我在处理之前使用
typeof
运算符进行检查。但查看此链接,似乎许多 javascript 实例(例如数组或正则表达式)都被键入为对象。
我需要我的论点是一个纯粹的对象(像这样:
{key: value, . . .}
)。
他们有什么方法可以检查变量是否是纯对象,而不必为每个对象实例运行特定测试,例如
Array.isArray()
?
为了达到预期的结果,请使用以下查找构造函数名称的选项来检查变量是否是纯javascript对象
根据 MDN,
所有对象(除了使用 Object.create(null)) 将具有构造函数属性。创建的对象 没有显式使用构造函数(即对象 和数组文字)将有一个指向的构造函数属性 该对象的基本对象构造函数类型。
请参阅此链接了解有关构造函数属性的更多详细信息 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor
var x = {a:1,b:2};
var y = [1,2,3];
console.log(x.constructor.name === "Object")//x.constructor.name is Object
console.log(y.constructor.name === "Object")//y.constructor.name is Array
您可以检查原型:
function isPureObject(input) {
return null !== input &&
typeof input === 'object' &&
Object.getPrototypeOf(input).isPrototypeOf(Object);
}
console.log(isPureObject({})); // true
console.log(isPureObject(new Object())); // true
console.log(isPureObject(undefined)); // false
console.log(isPureObject(null)); // false
console.log(isPureObject(1)); // false
console.log(isPureObject('a')); // false
console.log(isPureObject(false)); // false
console.log(isPureObject([])); // false
console.log(isPureObject(new Array())); // false
console.log(isPureObject(() => {})); // false
console.log(isPureObject(function () {})); // false
console.log(isPureObject(new Date())); // false
console.log(isPureObject(new RegExp())); // false
如果您只想检查“正常”纯对象(由
{...}
、JSON.parse(...)
等创建的对象),那么这个函数就可以工作
function is_pure_object(val) {
return val ? Object.getPrototypeOf(val)==Object.prototype : false
}
如果你还需要处理对象没有原型(非常罕见,仅由
Object.create(null)
创建),那么你需要进行额外的检查:
function is_pure_object2(val) {
if (!val)
return false
let proto = Object.getPrototypeOf(val)
return proto == Object.prototype || proto == null
}
其他解决方案的注意事项:
val.constructor
不可靠:
{constructor: 1}
Object.create(null)
Object.prototype.constructor
会出错Object.getPrototypeOf(val).isPrototypeOf(Object)
也不太理想:
Object.create(null)
Object.prototype.isPrototypeOf
会出错(
Object.prototype
被修改的可能性不大,但我以前处理过)
最短版本
const isObj = o => o?.constructor === Object;
由于“普通”或“纯”的定义,普通物体的检测有点问题。我使用以下方法来检测普通对象。我从不使用
x instanceof NodeList
类型验证,因为它们不适用于跨框架情况。 (每个窗口或框架都有自己的实例)
我认为这是检测普通物体最简单、最有效的方法。
function isPlainObject(o) {
var c = Object.prototype.toString.call(o) == '[object Object]'
&& o.constructor && o.constructor.name=="Object";
return c === true;
}
function myTestFunction(){
/* ... */
}
class myTestClass{
/* ... */
}
console.log( isPlainObject({"a":1,"b":2}) ); //true
console.log( isPlainObject({}) ); //true
console.log( isPlainObject(null) ); //false
console.log( isPlainObject("my string") ); //false
console.log( isPlainObject("") ); //false
console.log( isPlainObject([1,2,3]) ); //false
console.log( isPlainObject(document.querySelectorAll("*")) ); //false
console.log( isPlainObject(new RegExp(/[a-z]+/)) ); //false
console.log( isPlainObject(myTestFunction) ); //false
console.log( isPlainObject(new myTestFunction()) ); //false
console.log( isPlainObject(myTestClass) ); //false
console.log( isPlainObject(new myTestClass()) ); //false
使用lodash库,您可以通过以下函数实现此目的:
const isPureObject = _.isPlainObject({ foo: 'Zebra' });
expect(isPureObject).to.be.true;
const isMapPureObject = _.isPlainObject(new Map());
expect(isMapPureObject).to.be.false;
官方文档可以在这里找到。