mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-05-03 03:00:14 -04:00
[CS2] use _extends utility instead of Object.assign() for object spreads (#4675)
* _extends utility instead of Object.assign() * eqJS test for _extends * Test that a user-defined function named `_extends` doesn’t conflict with our utility function * IE8 polyfill note in docs
This commit is contained in:
committed by
Geoffrey Booth
parent
5525b2ba01
commit
b20e52da99
@@ -11,3 +11,5 @@ npm install --global coffeescript@next
|
||||
npm install --save-dev coffeescript@next babel-cli babel-preset-env
|
||||
coffee --print *.coffee | babel --presets env > app.js
|
||||
```
|
||||
|
||||
Note that [babel-preset-env](https://babeljs.io/docs/plugins/preset-env/) doesn’t automatically supply polyfills for your code. CoffeeScript itself will output [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) if you use the `in` operator, or destructuring or spread/rest syntax; and [`Function.bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) if you use a bound (`=>`) method in a class. Both are supported in Internet Explorer 9+ and all more recent browsers, but you will need to supply polyfills if you need to support Internet Explorer 8 or below and are using features that would cause these methods to be output, or in your own code are using similarly modern methods. One option is [`babel-polyfill`](https://babeljs.io/docs/usage/polyfill/), though there are many [other](https://hackernoon.com/polyfills-everything-you-ever-wanted-to-know-or-maybe-a-bit-less-7c8de164e423) [strategies](https://philipwalton.com/articles/loading-polyfills-only-when-needed/).
|
||||
|
||||
@@ -2242,7 +2242,7 @@
|
||||
// Object spread properties. https://github.com/tc39/proposal-object-rest-spread/blob/master/Spread.md
|
||||
// `obj2 = {a: 1, obj..., c: 3, d: 4}` → `obj2 = Object.assign({}, {a: 1}, obj, {c: 3, d: 4})`
|
||||
compileSpread(o) {
|
||||
var addSlice, j, len1, prop, propSlices, props, slices, splatSlice;
|
||||
var _extends, addSlice, j, len1, prop, propSlices, props, slices, splatSlice;
|
||||
props = this.properties;
|
||||
// Store object spreads.
|
||||
splatSlice = [];
|
||||
@@ -2271,7 +2271,8 @@
|
||||
if (!(slices[0] instanceof Obj)) {
|
||||
slices.unshift(new Obj);
|
||||
}
|
||||
return (new Call(new Literal('Object.assign'), slices)).compileToFragments(o);
|
||||
_extends = new Value(new Literal(utility('_extends', o)));
|
||||
return (new Call(_extends, slices)).compileToFragments(o);
|
||||
}
|
||||
|
||||
compileCSXAttributes(o) {
|
||||
@@ -5546,6 +5547,9 @@
|
||||
boundMethodCheck: function() {
|
||||
return "function(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new Error('Bound instance method accessed before binding'); } }";
|
||||
},
|
||||
_extends: function() {
|
||||
return "Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }";
|
||||
},
|
||||
// Shortcuts to speed up the lookup time for native functions.
|
||||
hasProp: function() {
|
||||
return '{}.hasOwnProperty';
|
||||
|
||||
@@ -1530,7 +1530,8 @@ exports.Obj = class Obj extends Base
|
||||
propSlices.push prop
|
||||
addSlice()
|
||||
slices.unshift new Obj unless slices[0] instanceof Obj
|
||||
(new Call new Literal('Object.assign'), slices).compileToFragments o
|
||||
_extends = new Value new Literal utility '_extends', o
|
||||
(new Call _extends, slices).compileToFragments o
|
||||
|
||||
compileCSXAttributes: (o) ->
|
||||
props = @properties
|
||||
@@ -3728,6 +3729,19 @@ UTILITIES =
|
||||
}
|
||||
}
|
||||
"
|
||||
_extends: -> "
|
||||
Object.assign || function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
"
|
||||
|
||||
# Shortcuts to speed up the lookup time for native functions.
|
||||
hasProp: -> '{}.hasOwnProperty'
|
||||
|
||||
@@ -897,3 +897,21 @@ test "#4566: destructuring with nested default values", ->
|
||||
|
||||
{e: {f = 5} = {}} = {}
|
||||
eq 5, f
|
||||
|
||||
test "#4674: _extends utility for object spreads 1", ->
|
||||
eqJS(
|
||||
"{a, b..., c..., d}"
|
||||
"""
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
_extends({a}, b, c, {d});
|
||||
"""
|
||||
)
|
||||
|
||||
test "#4674: _extends utility for object spreads 2", ->
|
||||
_extends = -> 3
|
||||
a = b: 1
|
||||
c = d: 2
|
||||
e = {a..., c...}
|
||||
eq e.b, 1
|
||||
eq e.d, 2
|
||||
|
||||
Reference in New Issue
Block a user