domenic at domenicdenicola.com (2013-10-26T03:22:15.356Z)
> Traceur has:
>
> ```js
> function assign(target, source) {
> var props = $getOwnPropertyNames(source);
> var p, length = props.length;
> for (p = 0; p < length; p++) {
> target[props[p]] = source[props[p]];
> }
> return target;
> }
> ```
>
> Which is correct.
Almost correct ;-)
Exception handling and enumerable checks are missing. And calling
$getOwnPropertyNames() is not fully compatible when compared to
[[OwnKeys]] in some Proxy corner cases [1], but that's difficult to get
right in ES5 code.
[1]: https://github.com/anba/es6draft/blob/master/src/test/scripts/suite/objects/Object/assign.js#L166-L181
A more conformant implementation should be this one:
```js
function assign(target, source) {
function ToObject(o) {
if (o == null) {
throw new TypeError();
}
return Object(o);
}
var to = ToObject(target);
var from = ToObject(source);
var keys = $getOwnPropertyNames(from);
var pendingException = null;
for (var i = 0, length = keys.length; i < length; ++i) {
var nextKey = keys[i];
try {
var desc = $getOwnPropertyDescriptor(from, nextKey);
if (desc !== undefined && desc.enumerable) {
to[nextKey] = from[nextKey];
}
} catch (e) {
if (pendingException !== null) {
pendingException = e;
}
}
}
if (pendingException !== null) {
throw pendingException;
}
return to;
}
```
> Traceur has: > > function assign(target, source) { > var props = $getOwnPropertyNames(source); > var p, length = props.length; > for (p = 0; p < length; p++) { > target[props[p]] = source[props[p]]; > } > return target; > } > > Which is correct. Almost correct ;-) Exception handling and enumerable checks are missing. And calling $getOwnPropertyNames() is not fully compatible when compared to [[OwnKeys]] in some Proxy corner cases [1], but that's difficult to get right in ES5 code. [1] https://github.com/anba/es6draft/blob/master/src/test/scripts/suite/objects/Object/assign.js#L166-L181 A more conformant implementation should be this one: function assign(target, source) { function ToObject(o) { if (o == null) { throw new TypeError(); } return Object(o); } var to = ToObject(target); var from = ToObject(source); var keys = $getOwnPropertyNames(from); var pendingException = null; for (var i = 0, length = keys.length; i < length; ++i) { var nextKey = keys[i]; try { var desc = $getOwnPropertyDescriptor(from, nextKey); if (desc !== undefined && desc.enumerable) { to[nextKey] = from[nextKey]; } } catch (e) { if (pendingException !== null) { pendingException = e; } } } if (pendingException !== null) { throw pendingException; } return to; } - André