termi / es6-transpiler

Tomorrow's JavaScript syntax today
Other
216 stars 18 forks source link

Support differences of spread operator with spec #38

Open iamdustan opened 10 years ago

iamdustan commented 10 years ago

This bit of code works perfectly fine with Traceur.

var $$ = (selector, context=document) => [...context.querySelectorAll(selector)];

With the es6-transpiler the output is:

var $$ = function(selector)  {function ITER$0(v,f){var $Symbol_iterator=typeof Symbol!=='undefined'&&Symbol.iterator||'@@iterator';if(v){if(Array.isArray(v))return f?v.slice():v;var i,r;if(typeof v==='object'&&typeof (f=v[$Symbol_iterator])==='function'){i=f.call(v);r=[];while((f=i['next']()),f['done']!==true)r.push(f['value']);return r;}}throw new Error(v+' is not iterable')};var context = arguments[1];if(context === void 0)context = document;
      return [].concat(ITER$0((context).querySelectorAll(selector)));
    };

and the following error is thrown:

Uncaught Error: [object NodeList] is not iterable.

Is this expected and part of the not-yet-supported iterator-able pieces?

termi commented 10 years ago

This problem is on specification side. In current version of spec spread operation is only allowed on Array or on objects with Iterator protocol implementation. It doesn't allow on array-like objects like {0: 'first', length: 1} I am fired a bug about this problem https://bugs.ecmascript.org/show_bug.cgi?id=2034 (invalid)

btw, the current version of traceur does not support this: http://google.github.io/traceur-compiler/demo/repl.html#debugger%3B%0A%0Avar%20a%20%3D%20%5B...document.querySelectorAll('div')%5D throw a error: TypeError: Cannot spread non-iterable object.

Update: i am sorry this link is invalid, I can't find a valid link right now

termi commented 10 years ago

The easiest way for you is to implement Iterator Protocol on NodeList. Something like this:

var $Symbol_iterator=typeof Symbol!=='undefined'&&Symbol.iterator||'@@iterator';
NodeList[$Symbol] = function() {
  return {
    next: function() {//do it
    }
  }
}
iamdustan commented 10 years ago

Ah. That worked in a previous version of traceur.

Using the following syntax works in Firefox Nightly 33, but not in es6-transpiler or traceur.

var els = document.querySelectorAll('*');
var arr = [for (_ of els) _];
console.log(arr); // => []<Node>’s
iamdustan commented 10 years ago

Also, is the '@@iterator' name still spec or has it changed to some private Symbol or something thereabouts. Is this level of implementation detail a concern or goal of es6-transpiler? Thanks @termi.

termi commented 10 years ago

@iamdustan The goal of es6-transpiler is to support Symbol.iterator. The '@@iterator' is just a fallback