te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - `new Object` vs `Object` in the ECMAScript spec - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - `new Object` vs `Object` in the ECMAScript spec - Stack Overflow

programmeradmin2浏览0评论

So, I'm looking at the ES5 specification at the definition of what new Object and Object do. To my surprise:

  • new Object describes a whole algorithm of how the object constructor works - treating what happens with different kinds of values. Basically calls ToObject on non objects - identity on objects and builds on null and undefined.
  • Object has a special first step for null and undefined where it builds an object and then calls ToObject on primitives and identity on objects.

After reading the description a few times - they seem identical. However, clearly from the spec they do something different. For example in Array - calling new Array is specified as the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.`

So - what is the difference between new Object and Object? Why were they specified differently?

For ease - here's a link to the spec.

So, I'm looking at the ES5 specification at the definition of what new Object and Object do. To my surprise:

  • new Object describes a whole algorithm of how the object constructor works - treating what happens with different kinds of values. Basically calls ToObject on non objects - identity on objects and builds on null and undefined.
  • Object has a special first step for null and undefined where it builds an object and then calls ToObject on primitives and identity on objects.

After reading the description a few times - they seem identical. However, clearly from the spec they do something different. For example in Array - calling new Array is specified as the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.`

So - what is the difference between new Object and Object? Why were they specified differently?

For ease - here's a link to the spec.

Share Improve this question asked Jun 12, 2015 at 11:03 Benjamin GruenbaumBenjamin Gruenbaum 276k89 gold badges518 silver badges514 bronze badges 15
  • JS room people (namely Jan Drovak) guessed it has to do with host objects but I couldn't figure out one that actually made a difference. – Benjamin Gruenbaum Commented Jun 12, 2015 at 11:03
  • new Object is implementation-defined on host objects. I'd still like to see an example of when it is not an identity. – John Dvorak Commented Jun 12, 2015 at 11:05
  • 14 Is this going to be one of those famous questions? – user3117575 Commented Jun 12, 2015 at 11:09
  • When Object is called as part of a new expression, it is a constructor that may create an object. which concerns If the value is a host object, then actions are taken and a result is returned in an implementation-dependent manner that may depend on the host object. and this is implementation dependant. ToObject - Object: The result is the input argument (no conversion). This seems to be the primary difference. Why? Probably to allow the implementation dependant part – Xotic750 Commented Jun 12, 2015 at 11:44
  • 1 Why not ask on esdiscuss? – Felix Kling Commented Jun 12, 2015 at 15:29
 |  Show 10 more ments

1 Answer 1

Reset to default 16

Object(window) will never clone window but new Object(window) might. All current -- potentially all known -- implementations just return the same reference, although the spec allows for implementation-defined behavior.

The steps for 15.2.1.1 say:

  1. If value is null, undefined or not supplied, create and return a new Object object exactly as if the standard built-in Object constructor had been called with the same arguments
  2. Return ToObject(value).

The definition of ToObject (9.9) lists a few types that will be caught by step 1 (in table 14), but for Object has a very simple definition:

The result is the input argument (no conversion).

It explicitly states that the input argument will be returned as-is, so they should be equal references (===).

The definition for new Object (15.2.2.1) has a similar chain of type-checks in step 1, but the step for objects (1.a) is:

i. If the value is a native ECMAScript object, do not create a new object but simply return value.

ii. If the value is a host object, then actions are taken and a result is returned in an implementation-dependent manner that may depend on the host object.

That is, for any host object foo, the call Object(foo) must === foo but new Object(foo) may === foo.

Host objects are defined in 4.3.8 to be

object supplied by the host environment to plete the execution environment of ECMAScript.

This answer lists a few host objects to include window, history, etc. Running those through new Object(foo) should (but doesn't have to) return a different object.

In any case but passing a host object, new Object(foo) seems to be a more plicated chain that defers to ToObject in much the same way as Object(foo).

Unfortunately, 15.2.2.1.1.a.ii states that the "result is returned in an implementation-dependent manner" and has no specifics as to the "actions [that] are taken" and it appears that Chrome will return the same object (equal references) for all of the listed "host objects."

Using this script to check:

var objects = [
  /* Native objects */
  'Object', 'Date', 'Math', 'parseInt', 'eval',
  /* Host objects */
  'window', 'document', 'location', 'history', 'XMLHttpRequest', 'setTimeout'
];

function getDefinedReference(name) {
  if (eval('typeof ' + name) !== 'undefined') {
    return eval(name);
  } else {
    throw new Error('' + name + ' is not defined.');
  }
}

function checkIdentity(name) {
  try {
    var ref = getDefinedReference(name);
    var no = new Object(ref);
    var o = Object(ref);

    console.log(name, ref === no, ref === o, no === o);

    if (ref === o && no !== o) {
      // Make sure ref === Object(ref) but not new Object(ref)
      console.log(name, 'returns different references.');
    }
  } catch (e) {
    console.warn(e);
  }
}

objects.forEach(checkIdentity);

if (typeof window !== 'undefined') {
  for (var f in window) {
    checkIdentity(f);
  }
}

doesn't find any objects where Object and new Object behave differently. @Xotic750 seems to be right that it can be implementation-dependent, but nobody is using it.

发布评论

评论列表(0)

  1. 暂无评论