Javascript 中如何判断一个对象是否是对象字面量?

发布于 2024-07-29 08:18:13 字数 240 浏览 9 评论 0原文

有没有办法确定 Javascript 中是否使用 object-literal< 创建对象/a> 表示法还是使用构造函数方法?

在我看来,您只是访问它的父对象,但是如果您传入的对象没有对其父对象的引用,我认为您无法分辨这一点,可以吗?

Is there any way to determine in Javascript if an object was created using object-literal notation or using a constructor method?

It seems to me that you just access it's parent object, but if the object you are passing in doesn't have a reference to it's parent, I don't think you can tell this, can you?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

猫腻 2024-08-05 08:18:13

您想要的是:

Object.getPrototypeOf(obj) === Object.prototype

这会检查该对象是否是使用 new Object(){...} 创建的普通对象,而不是 Object 的某个子类

What you want is:

Object.getPrototypeOf(obj) === Object.prototype

This checks that the object is a plain object created with either new Object() or {...} and not some subclass of Object.

请叫√我孤独 2024-08-05 08:18:13

我刚刚在一次甜蜜的 hackfest 中遇到了这个问题和线程,其中涉及一个 grail 任务,用于评估对象是使用 {} 还是 new Object() 创建的(我仍然没有弄清楚。)

无论如何,我很惊讶地发现了相似之处此处发布的 isObjectLiteral() 函数和我自己为 Pollen.JS 项目编写的 isObjLiteral() 函数之间。 我相信这个解决方案是在我提交 Pollen.JS 之前发布的,所以 - 向您致敬! 我的优点是长度......不到一半(当包括你的设置例程时),但两者都会产生相同的结果。

看一下:

function isObjLiteral(_obj) {
  var _test  = _obj;
  return (  typeof _obj !== 'object' || _obj === null ?
              false :  
              (
                (function () {
                  while (!false) {
                    if (  Object.getPrototypeOf( _test = Object.getPrototypeOf(_test)  ) === null) {
                      break;
                    }      
                  }
                  return Object.getPrototypeOf(_obj) === _test;
                })()
              )
          );
}

另外,一些测试内容:

var _cases= {
    _objLit : {}, 
    _objNew : new Object(),
    _function : new Function(),
    _array : new Array(), 
    _string : new String(),
    _image : new Image(),
    _bool: true
};

console.dir(_cases);

for ( var _test in _cases ) {
  console.group(_test);
  console.dir( {
    type:    typeof _cases[_test], 
    string:  _cases[_test].toString(), 
    result:  isObjLiteral(_cases[_test])  
  });    
  console.groupEnd();
}

或者在 jsbin.com 上...

http://jsbin.com/iwuwa

当你到达那里时一定要打开 firebug - 调试文档是为了 IE 爱好者。

I just came across this question and thread during a sweet hackfest that involved a grail quest for evaluating whether an object was created with {} or new Object() (i still havent figured that out.)

Anyway, I was suprised to find the similarity between the isObjectLiteral() function posted here and my own isObjLiteral() function that I wrote for the Pollen.JS project. I believe this solution was posted prior to my Pollen.JS commit, so - hats off to you! The upside to mine is the length... less then half (when included your set up routine), but both produce the same results.

Take a look:

function isObjLiteral(_obj) {
  var _test  = _obj;
  return (  typeof _obj !== 'object' || _obj === null ?
              false :  
              (
                (function () {
                  while (!false) {
                    if (  Object.getPrototypeOf( _test = Object.getPrototypeOf(_test)  ) === null) {
                      break;
                    }      
                  }
                  return Object.getPrototypeOf(_obj) === _test;
                })()
              )
          );
}

Additionally, some test stuff:

var _cases= {
    _objLit : {}, 
    _objNew : new Object(),
    _function : new Function(),
    _array : new Array(), 
    _string : new String(),
    _image : new Image(),
    _bool: true
};

console.dir(_cases);

for ( var _test in _cases ) {
  console.group(_test);
  console.dir( {
    type:    typeof _cases[_test], 
    string:  _cases[_test].toString(), 
    result:  isObjLiteral(_cases[_test])  
  });    
  console.groupEnd();
}

Or on jsbin.com...

http://jsbin.com/iwuwa

Be sure to open firebug when you get there - debugging to the document is for IE lovers.

行雁书 2024-08-05 08:18:13

编辑:我将“对象文字”解释为使用对象文字 Object 构造函数创建的任何内容。 这很可能就是约翰·雷西格的意思。

我有一个函数,即使 .constructor 被污染或者对象是在另一个框架中创建的,它也可以工作。 请注意,Object.prototype.toString.call(obj) === "[object Object]"(正如某些人可能认为的那样)不会解决此问题。

function isObjectLiteral(obj) {
    if (typeof obj !== "object" || obj === null)
        return false;

    var hasOwnProp = Object.prototype.hasOwnProperty,
    ObjProto = obj;

    // get obj's Object constructor's prototype
    while (Object.getPrototypeOf(ObjProto = Object.getPrototypeOf(ObjProto)) !== null);

    if (!Object.getPrototypeOf.isNative) // workaround if non-native Object.getPrototypeOf
        for (var prop in obj)
            if (!hasOwnProp.call(obj, prop) && !hasOwnProp.call(ObjProto, prop)) // inherited elsewhere
                return false;

    return Object.getPrototypeOf(obj) === ObjProto;
};


if (!Object.getPrototypeOf) {
    if (typeof ({}).__proto__ === "object") {
        Object.getPrototypeOf = function (obj) {
            return obj.__proto__;
        };
        Object.getPrototypeOf.isNative = true;
    } else {
        Object.getPrototypeOf = function (obj) {
            var constructor = obj.constructor,
            oldConstructor;
            if (Object.prototype.hasOwnProperty.call(obj, "constructor")) {
                oldConstructor = constructor;
                if (!(delete obj.constructor)) // reset constructor
                    return null; // can't delete obj.constructor, return null
                constructor = obj.constructor; // get real constructor
                obj.constructor = oldConstructor; // restore constructor
            }
            return constructor ? constructor.prototype : null; // needed for IE
        };
        Object.getPrototypeOf.isNative = false;
    }
} else Object.getPrototypeOf.isNative = true;

以下是测试用例的 HTML:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <!-- Online here: http://code.eligrey.com/testcases/all/isObjectLiteral.html -->
    <title>isObjectLiteral</title>
    <style type="text/css">
    li { background: green; } li.FAIL { background: red; }
    iframe { display: none; }
    </style>
</head>
<body>
<ul id="results"></ul>
<script type="text/javascript">
function isObjectLiteral(obj) {
    if (typeof obj !== "object" || obj === null)
        return false;

    var hasOwnProp = Object.prototype.hasOwnProperty,
    ObjProto = obj;

    // get obj's Object constructor's prototype
    while (Object.getPrototypeOf(ObjProto = Object.getPrototypeOf(ObjProto)) !== null);

    if (!Object.getPrototypeOf.isNative) // workaround if non-native Object.getPrototypeOf
        for (var prop in obj)
            if (!hasOwnProp.call(obj, prop) && !hasOwnProp.call(ObjProto, prop)) // inherited elsewhere
                return false;

    return Object.getPrototypeOf(obj) === ObjProto;
};


if (!Object.getPrototypeOf) {
    if (typeof ({}).__proto__ === "object") {
        Object.getPrototypeOf = function (obj) {
            return obj.__proto__;
        };
        Object.getPrototypeOf.isNative = true;
    } else {
        Object.getPrototypeOf = function (obj) {
            var constructor = obj.constructor,
            oldConstructor;
            if (Object.prototype.hasOwnProperty.call(obj, "constructor")) {
                oldConstructor = constructor;
                if (!(delete obj.constructor)) // reset constructor
                    return null; // can't delete obj.constructor, return null
                constructor = obj.constructor; // get real constructor
                obj.constructor = oldConstructor; // restore constructor
            }
            return constructor ? constructor.prototype : null; // needed for IE
        };
        Object.getPrototypeOf.isNative = false;
    }
} else Object.getPrototypeOf.isNative = true;

// Function serialization is not permitted
// Does not work across all browsers
Function.prototype.toString = function(){};

// The use case that we want to match
log("{}", {}, true);

// Instantiated objects shouldn't be matched
log("new Date", new Date, false);

var fn = function(){};

// Makes the function a little more realistic
// (and harder to detect, incidentally)
fn.prototype = {someMethod: function(){}};

// Functions shouldn't be matched
log("fn", fn, false);

// Again, instantiated objects shouldn't be matched
log("new fn", new fn, false);

var fn2 = function(){};

log("new fn2", new fn2, false);

var fn3 = function(){};

fn3.prototype = {}; // impossible to detect (?) without native Object.getPrototypeOf

log("new fn3 (only passes with native Object.getPrototypeOf)", new fn3, false);

log("null", null, false);

log("undefined", undefined, false);


/* Note:
 * The restriction against instantiated functions is
 * due to the fact that this method will be used for
 * deep-cloning an object. Instantiated objects will
 * just have their reference copied over, whereas
 * plain objects will need to be completely cloned.
 */

var iframe = document.createElement("iframe");
document.body.appendChild(iframe);

var doc = iframe.contentDocument || iframe.contentWindow.document;
doc.open();
doc.write("<body onload='window.top.iframeDone(Object);'>");
doc.close();

function iframeDone(otherObject){
    // Objects from other windows should be matched
    log("new otherObject", new otherObject, true);
}

function log(msg, a, b) {
  var pass = isObjectLiteral(a) === b ? "PASS" : "FAIL";

  document.getElementById("results").innerHTML +=
    "<li class='" + pass + "'>" + msg + "</li>";
}


</script>
</body>
</html>

Edit: I'm interpreting "object literal" as anything created using an object literal or the Object constructor. This is what John Resig most likely meant.

I have a function that will work even if .constructor has been tainted or if the object was created in another frame. Note that Object.prototype.toString.call(obj) === "[object Object]" (as some may believe) will not solve this problem.

function isObjectLiteral(obj) {
    if (typeof obj !== "object" || obj === null)
        return false;

    var hasOwnProp = Object.prototype.hasOwnProperty,
    ObjProto = obj;

    // get obj's Object constructor's prototype
    while (Object.getPrototypeOf(ObjProto = Object.getPrototypeOf(ObjProto)) !== null);

    if (!Object.getPrototypeOf.isNative) // workaround if non-native Object.getPrototypeOf
        for (var prop in obj)
            if (!hasOwnProp.call(obj, prop) && !hasOwnProp.call(ObjProto, prop)) // inherited elsewhere
                return false;

    return Object.getPrototypeOf(obj) === ObjProto;
};


if (!Object.getPrototypeOf) {
    if (typeof ({}).__proto__ === "object") {
        Object.getPrototypeOf = function (obj) {
            return obj.__proto__;
        };
        Object.getPrototypeOf.isNative = true;
    } else {
        Object.getPrototypeOf = function (obj) {
            var constructor = obj.constructor,
            oldConstructor;
            if (Object.prototype.hasOwnProperty.call(obj, "constructor")) {
                oldConstructor = constructor;
                if (!(delete obj.constructor)) // reset constructor
                    return null; // can't delete obj.constructor, return null
                constructor = obj.constructor; // get real constructor
                obj.constructor = oldConstructor; // restore constructor
            }
            return constructor ? constructor.prototype : null; // needed for IE
        };
        Object.getPrototypeOf.isNative = false;
    }
} else Object.getPrototypeOf.isNative = true;

Here is the HTML for the testcase:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <!-- Online here: http://code.eligrey.com/testcases/all/isObjectLiteral.html -->
    <title>isObjectLiteral</title>
    <style type="text/css">
    li { background: green; } li.FAIL { background: red; }
    iframe { display: none; }
    </style>
</head>
<body>
<ul id="results"></ul>
<script type="text/javascript">
function isObjectLiteral(obj) {
    if (typeof obj !== "object" || obj === null)
        return false;

    var hasOwnProp = Object.prototype.hasOwnProperty,
    ObjProto = obj;

    // get obj's Object constructor's prototype
    while (Object.getPrototypeOf(ObjProto = Object.getPrototypeOf(ObjProto)) !== null);

    if (!Object.getPrototypeOf.isNative) // workaround if non-native Object.getPrototypeOf
        for (var prop in obj)
            if (!hasOwnProp.call(obj, prop) && !hasOwnProp.call(ObjProto, prop)) // inherited elsewhere
                return false;

    return Object.getPrototypeOf(obj) === ObjProto;
};


if (!Object.getPrototypeOf) {
    if (typeof ({}).__proto__ === "object") {
        Object.getPrototypeOf = function (obj) {
            return obj.__proto__;
        };
        Object.getPrototypeOf.isNative = true;
    } else {
        Object.getPrototypeOf = function (obj) {
            var constructor = obj.constructor,
            oldConstructor;
            if (Object.prototype.hasOwnProperty.call(obj, "constructor")) {
                oldConstructor = constructor;
                if (!(delete obj.constructor)) // reset constructor
                    return null; // can't delete obj.constructor, return null
                constructor = obj.constructor; // get real constructor
                obj.constructor = oldConstructor; // restore constructor
            }
            return constructor ? constructor.prototype : null; // needed for IE
        };
        Object.getPrototypeOf.isNative = false;
    }
} else Object.getPrototypeOf.isNative = true;

// Function serialization is not permitted
// Does not work across all browsers
Function.prototype.toString = function(){};

// The use case that we want to match
log("{}", {}, true);

// Instantiated objects shouldn't be matched
log("new Date", new Date, false);

var fn = function(){};

// Makes the function a little more realistic
// (and harder to detect, incidentally)
fn.prototype = {someMethod: function(){}};

// Functions shouldn't be matched
log("fn", fn, false);

// Again, instantiated objects shouldn't be matched
log("new fn", new fn, false);

var fn2 = function(){};

log("new fn2", new fn2, false);

var fn3 = function(){};

fn3.prototype = {}; // impossible to detect (?) without native Object.getPrototypeOf

log("new fn3 (only passes with native Object.getPrototypeOf)", new fn3, false);

log("null", null, false);

log("undefined", undefined, false);


/* Note:
 * The restriction against instantiated functions is
 * due to the fact that this method will be used for
 * deep-cloning an object. Instantiated objects will
 * just have their reference copied over, whereas
 * plain objects will need to be completely cloned.
 */

var iframe = document.createElement("iframe");
document.body.appendChild(iframe);

var doc = iframe.contentDocument || iframe.contentWindow.document;
doc.open();
doc.write("<body onload='window.top.iframeDone(Object);'>");
doc.close();

function iframeDone(otherObject){
    // Objects from other windows should be matched
    log("new otherObject", new otherObject, true);
}

function log(msg, a, b) {
  var pass = isObjectLiteral(a) === b ? "PASS" : "FAIL";

  document.getElementById("results").innerHTML +=
    "<li class='" + pass + "'>" + msg + "</li>";
}


</script>
</body>
</html>
白首有我共你 2024-08-05 08:18:13

听起来您正在寻找这个:

function Foo() {}

var a = {};
var b = new Foo();

console.log(a.constructor == Object); // true
console.log(b.constructor == Object); // false

对象的构造函数属性是指向用于构造它的函数的指针。 在上面的示例中,b.constructor == Foo。 如果对象是使用大括号(数组文字表示法)或使用 new Object() 创建的,则其构造函数属性将为 == Object

更新:crescentfresh指出$(document).constructor == Object而不是等于jQuery构造函数,所以我做了更多的挖掘。 似乎通过使用对象文字作为对象的原型,您使构造函数属性几乎毫无价值:

function Foo() {}
var obj = new Foo();
obj.constructor == Object; // false

但是:

function Foo() {}
Foo.prototype = { objectLiteral: true };
var obj = new Foo();
obj.constructor == Object; // true

在另一个答案中有一个很好的解释 这里,以及更复杂的解释这里

我认为其他答案是正确的,并且没有真正的方法来检测这一点。

It sounds like you are looking for this:

function Foo() {}

var a = {};
var b = new Foo();

console.log(a.constructor == Object); // true
console.log(b.constructor == Object); // false

The constructor property on an object is a pointer to the function that is used to construct it. In the example above b.constructor == Foo. If the object was created using curly brackets (the array literal notation) or using new Object() then its constructor property will == Object.

Update: crescentfresh pointed out that $(document).constructor == Object rather than being equal to the jQuery constructor, so I did a little more digging. It seems that by using an object literal as the prototype of an object you render the constructor property almost worthless:

function Foo() {}
var obj = new Foo();
obj.constructor == Object; // false

but:

function Foo() {}
Foo.prototype = { objectLiteral: true };
var obj = new Foo();
obj.constructor == Object; // true

There is a very good explanation of this in another answer here, and a more involved explanation here.

I think the other answers are correct and there is not really a way to detect this.

思念满溢 2024-08-05 08:18:13

对象字面量是用于定义对象的符号 - 在 javascript 中始终采用大括号括起来的名称-值对的形式。 一旦执行完毕,就无法判断该对象是否是通过此表示法创建的(实际上,我认为这可能过于简化,但基本上是正确的)。 你只是有一个对象。 这是 js 的伟大之处之一,因为有很多捷径可以完成可能要写很长时间的事情。 简而言之,文字符号取代了必须编写的内容:

var myobject = new Object();

An object literal is the notation you use to define an object - which in javascript is always in the form of a name-value pair surrounded by the curly brackets. Once this has been executed there is no way to tell if the object was created by this notation or not (actually, I think that might be an over-simplification, but basically correct). You just have an object. This is one of the great things about js in that there are a lot of short cuts to do things that might be a lot longer to write. In short, the literal notation replaces having to write:

var myobject = new Object();
薆情海 2024-08-05 08:18:13

我遇到了同样的问题,所以我决定这样做:

function isPlainObject(val) {
  return val ? val.constructor === {}.constructor : false;
}
// Examples:
isPlainObject({}); // true
isPlainObject([]); // false
isPlainObject(new Human("Erik", 25)); // false
isPlainObject(new Date); // false
isPlainObject(new RegExp); // false
//and so on...

I had the same issue, so I decide to go this way:

function isPlainObject(val) {
  return val ? val.constructor === {}.constructor : false;
}
// Examples:
isPlainObject({}); // true
isPlainObject([]); // false
isPlainObject(new Human("Erik", 25)); // false
isPlainObject(new Date); // false
isPlainObject(new RegExp); // false
//and so on...
小傻瓜 2024-08-05 08:18:13

没有办法区分从对象字面量构建的对象和从其他方式构建的对象之间的区别。

这有点像问你是否可以确定一个数值变量是否是通过赋值“2”或“3-1”来构造的;

如果您需要这样做,则必须将一些特定的签名放入对象文本中以便稍后检测。

There is no way to tell the difference between an object built from an object literal, and one built from other means.

It's a bit like asking if you can determine whether a numeric variable was constructed by assigning the value '2' or '3-1';

If you need to do this, you'd have to put some specific signature into your object literal to detect later.

掩耳倾听 2024-08-05 08:18:13

现在有一个更优雅的解决方案可以准确回答您的问题:

function isObject(value) {
  return value !== null && value !== undefined && Object.is(value.constructor, Object)
}

// Test stuff below //

class MyClass extends Object {
  constructor(args) {
    super(args)
  }
  say() {
    console.log('hello')
  }
}

function MyProto() {
  Object.call(this)
}
MyProto.prototype = Object.assign(Object.create(Object.prototype), {

  constructor: MyProto,

  say: function() {
    console.log('hello')
  }

});

const testsCases = {
  objectLiteral: {},
  objectFromNew: new Object(),
  null: null,
  undefined: undefined,
  number: 123,
  function: new Function(),
  array: new Array([1, 2, 3]),
  string: new String('foobar'),
  image: new Image(),
  bool: true,
  error: new Error('oups'),
  myClass: new MyClass(),
  myProto: new MyProto()
}

for (const [key, value] of Object.entries(testsCases)) {
  console.log(`${key.padEnd(15)} => ${isObject(value)}`)
}

此致

Nowaday there is a more elegant solution that respond exactly to your question:

function isObject(value) {
  return value !== null && value !== undefined && Object.is(value.constructor, Object)
}

// Test stuff below //

class MyClass extends Object {
  constructor(args) {
    super(args)
  }
  say() {
    console.log('hello')
  }
}

function MyProto() {
  Object.call(this)
}
MyProto.prototype = Object.assign(Object.create(Object.prototype), {

  constructor: MyProto,

  say: function() {
    console.log('hello')
  }

});

const testsCases = {
  objectLiteral: {},
  objectFromNew: new Object(),
  null: null,
  undefined: undefined,
  number: 123,
  function: new Function(),
  array: new Array([1, 2, 3]),
  string: new String('foobar'),
  image: new Image(),
  bool: true,
  error: new Error('oups'),
  myClass: new MyClass(),
  myProto: new MyProto()
}

for (const [key, value] of Object.entries(testsCases)) {
  console.log(`${key.padEnd(15)} => ${isObject(value)}`)
}

Best regards

雪花飘飘的天空 2024-08-05 08:18:13
typeof obj === 'object' && obj !== null && Object.getPrototypeOf(obj) === Object.prototype

下面所有 return false 都

123
null
undefined
'abc'
false
true
[]
new Number()
new Boolean()
() => {}
function () {}

比杰西的答案有所改进

typeof obj === 'object' && obj !== null && Object.getPrototypeOf(obj) === Object.prototype

below all return false

123
null
undefined
'abc'
false
true
[]
new Number()
new Boolean()
() => {}
function () {}

an improvement over jesse's answer

强者自强 2024-08-05 08:18:13

这对我有用

const isObjectLiteral = (val) => {
    return (
        val &&
        Object.prototype.toString.call(val) === '[object Object]' &&
        ((val as ObjectLiteral).constructor === Object ||
            Object.getPrototypeOf(val) === null)
    )
}

所有这些都会检查,没有别的:

  • {...}
  • new Object({})
  • Object.create(null)< /code>
  • Object.create({sample: 12})

This is what works for me

const isObjectLiteral = (val) => {
    return (
        val &&
        Object.prototype.toString.call(val) === '[object Object]' &&
        ((val as ObjectLiteral).constructor === Object ||
            Object.getPrototypeOf(val) === null)
    )
}

All of this will check, nothing else:

  • {...}
  • new Object({})
  • Object.create(null)
  • Object.create({sample: 12})
酒中人 2024-08-05 08:18:13

11 年前的问题是我的简洁解决方案,欢迎边缘案例建议;
步骤-> 查找对象然后比较以检查属性 -> 对象字面量没有长度、原型和边缘情况的 stringyfy 属性。

尝试测试 JSON 和
Object.create(Object.create({cool: "joes"})).

 "use strict"
let isObjectL = a => { 
        if (typeof a !=='object' || ['Number','String','Boolean', 'Symbol'].includes(a.constructor.name)) return false;
       let props = Object.getOwnPropertyNames(a);
        if ( !props.includes('length') && !props.includes('prototype') || !props.includes('stringify')) return true;
         };


let A={type:"Fiat", model:"500", color:"white"};
let B= new Object();
let C = { "name":"John", "age":30, "city":"New York"};
let D= '{ "name":"John", "age":30, "city":"New York"}';
let E = JSON.parse(D);
let F = new Boolean();
let G = new Number();
    
    console.log(isObjectL(A));
    
    console.log(isObjectL(B));
    
    console.log(isObjectL(C));
    
    console.log(isObjectL(D));
    
    console.log(isObjectL(E));
    
    console.log(isObjectL(JSON));
    
    console.log(isObjectL(F));
    
    console.log(isObjectL(G));
    
    console.log(isObjectL(
Object.create(Object.create({cool: "joes"}))));

    
    console.log(isObjectL());

显示内部工作的另一种变体

isObject=function(a) { 
    let exclude = ['Number','String','Boolean', 'Symbol'];
    let types = typeof a;
    let props = Object.getOwnPropertyNames(a);
    console.log((types ==='object' && !exclude.includes(a.constructor.name) &&
    ( !props.includes('length') && !props.includes('prototype') && !props.includes('stringify'))));
    return `type: ${types} props: ${props}
    ----------------`}
    
    A={type:"Fiat", model:"500", color:"white"};
B= new Object();
C = { "name":"John", "age":30, "city":"New York"};
D= '{ "name":"John", "age":30, "city":"New York"}';
E = JSON.parse(D);
F = new Boolean();
G = new Number();
    
    console.log(isObject(A));
    
    console.log(isObject(B));
    
    console.log(isObject(C));
    
    console.log(isObject(D));
    
    console.log(isObject(E));
    
    console.log(isObject(JSON));
    
    console.log(isObject(F));
    
    console.log(isObject(G));
    
    console.log(isObject(
Object.create(Object.create({cool: "joes"}))));

11 year old question here is my tidy solution, open to edge case suggestions;
steps -> look for objects only then compare to check properties -> object literals do not have length, prototype and for edge case stringyfy properties.

tried in test for JSON and
Object.create(Object.create({cool: "joes"})).

 "use strict"
let isObjectL = a => { 
        if (typeof a !=='object' || ['Number','String','Boolean', 'Symbol'].includes(a.constructor.name)) return false;
       let props = Object.getOwnPropertyNames(a);
        if ( !props.includes('length') && !props.includes('prototype') || !props.includes('stringify')) return true;
         };


let A={type:"Fiat", model:"500", color:"white"};
let B= new Object();
let C = { "name":"John", "age":30, "city":"New York"};
let D= '{ "name":"John", "age":30, "city":"New York"}';
let E = JSON.parse(D);
let F = new Boolean();
let G = new Number();
    
    console.log(isObjectL(A));
    
    console.log(isObjectL(B));
    
    console.log(isObjectL(C));
    
    console.log(isObjectL(D));
    
    console.log(isObjectL(E));
    
    console.log(isObjectL(JSON));
    
    console.log(isObjectL(F));
    
    console.log(isObjectL(G));
    
    console.log(isObjectL(
Object.create(Object.create({cool: "joes"}))));

    
    console.log(isObjectL());

Another variant showing inner working

isObject=function(a) { 
    let exclude = ['Number','String','Boolean', 'Symbol'];
    let types = typeof a;
    let props = Object.getOwnPropertyNames(a);
    console.log((types ==='object' && !exclude.includes(a.constructor.name) &&
    ( !props.includes('length') && !props.includes('prototype') && !props.includes('stringify'))));
    return `type: ${types} props: ${props}
    ----------------`}
    
    A={type:"Fiat", model:"500", color:"white"};
B= new Object();
C = { "name":"John", "age":30, "city":"New York"};
D= '{ "name":"John", "age":30, "city":"New York"}';
E = JSON.parse(D);
F = new Boolean();
G = new Number();
    
    console.log(isObject(A));
    
    console.log(isObject(B));
    
    console.log(isObject(C));
    
    console.log(isObject(D));
    
    console.log(isObject(E));
    
    console.log(isObject(JSON));
    
    console.log(isObject(F));
    
    console.log(isObject(G));
    
    console.log(isObject(
Object.create(Object.create({cool: "joes"}))));

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文