怎样判断一个对象是一个对象,在Javascript中的文字?(How to determine if

2019-07-30 16:55发布

有没有办法在Javascript,以确定是否一个对象是使用创建的对象的文字符号或使用构造方法?

在我看来,你只是访问它的父对象,但如果你是传入对象没有一个参考,以它的父母,我不认为你可以告诉这个,你能吗?

Answer 1:

我只是一个甜美的hackfest,涉及圣杯寻求评估对象是否与{}创建或新的对象()期间在这个问题和线程来(我仍然还没有想通了这一点。)

无论如何,我很惊讶找到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浏览器的爱好者。



Answer 2:

编辑:我解释“对象常量”作为使用对象文本创建任何Object的构造函数。 这是约翰Resig的最有可能的意思。

我有这是否会甚至工作的功能.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>


Answer 3:

这听起来像你正在寻找这样的:

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的构造函数,所以我做了一点挖掘。 看来,通过使用对象文本作为对象的原型您呈现constructor属性几乎一文不值:

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

但:

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

还有就是这个在另一个答案很好的解释在这里 ,和更为复杂的解释在这里 。

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



Answer 4:

文字的目的是用于定义对象的符号 - 这在JavaScript总是在一个名称 - 值对由大括号包围的形式。 一旦这个已经执行的没有办法告诉如果对象被这个符号或不创建(实际上,我认为这可能是一个过于简单化,但基本上是正确的)。 你只需要一个对象。 这是在有很多走捷径的做的事情,可能是长了不少写JS的伟大的事情之一。 总之,文字符号替换不得不写:

var myobject = new Object();


Answer 5:

你想要的是:

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

此检查该对象是与任一创建一个普通的对象new Object(){...}和不一些子类Object



Answer 6:

有没有办法告诉一个来自其它方式建立从对象文本建立了一个对象,并且之间的差异。

这是一个有点像问,如果你能确定通过将值“2”或“3-1”的数值变量是否构建;

如果你需要做到这一点,你必须把一些特定的签名到您的对象文本后检测。



Answer 7:

我有同样的问题,所以我决定走这条路:

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...


文章来源: How to determine if an object is an object literal in Javascript?