> the spread operator

How?

JS:

var args = [0, 1, 2];
myFunction(...args);

Python:

args = [0, 1, 2]
myFunctions(*args)

A more complicated one:

JS:

var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);

Python:

args = [0, 1]
myFunction(-1, *args, 2, *[3])

As used in list building; JS:

var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];

Python:

parts = ['shoulders', 'knees']
lyrics = ['head', *parts, 'and', 'toes']

"A better way to concatenate arrays"; JS:

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];

Python:

arr1 = [0, 1, 2]
arr2 = [3, 4, 5]
arr1 = arr1 + arr2

(Though the star notation works here too.)

I omit JS's use of ... on objects; Python's class system works differently — and IMO, more rigorously — than JS's, making ... less sensible on Python objects. (Python focuses much less on passing around untyped key-value bags and more on strongly typed classes IMO; both are possible in both languages, but the idioms around them differ, and I think Python's idioms tend more towards having a well defined class with well defined attributes, and not having just a bag of attributes, moreso than JS at least, and I feel that direction (well defined classes) leads to more robust code. In particular, it forces you into naming your concepts, and defining their set of attributes: a simplistic type definition.)

> all functional Array methods

Python has map, reduce, etc., as well as generator and list comprehensions which are often easier to use.

> async functions

Python and JavaScript have practically identical syntax in this area.

> there's no acceptable way to pass a function body to another in Python

I find it very acceptable that if your function body is more complicated than an expression, that you're forced to pull it out and name it, frankly. I think it does good things for fighting complexity, and this just isn't something I worry about day to day while using Python. But I will concede that Python does lack a syntax for passing a function in an expression context.

(But I would also note JS's screwed up named-function syntax; in Python:

def foo():
# body

is a valid statement. JS's:

function foo() {
// body
}

is not a valid statement, and can only appear in certain, particular contexts. In particular, the following is not valid JavaScript, though many implementations will do The Right Thing™, I'm told:

if(true) {
function foo() {
// body.
}
}

[2])

> My code usually revolves around higher order functions, reduce(), map(), etc. I can't remember the last time I wrote a regular for loop in JavaScript.

Because JS for a long time (until ES6's for(… of …) syntax) lacked a for loop (the C style look, and for(… in …), do not count, as they do semantically different things), which is why you're using forEach().

> arrow functions

The best thing about arrow functions is the sane binding of `this`, a problem notably absent in Python to begin with.

> [Python's] class definition boilerplate is still hard to look at

This is sometimes true; I find the attrs[1] package helps greatly here for small, struct-like classes.

[1]: https://pypi.python.org/pypi/attrs

[2]: http://kangax.github.io/nfe/#expr-vs-decl