#554 enhancement
Juriy Zaytsev

`_each` to match native `forEach` behavior

Reported by Juriy Zaytsev | February 17th, 2009 @ 04:28 AM | in 1.7

Comments and changes to this ticket

  • Juriy Zaytsev
  • Andrew Dupont

    Andrew Dupont February 22nd, 2009 @ 05:35 AM

    • Tag changed from needs_patch, needs_tests to patched, tested
    • State changed from “new” to “enhancement”

    Hold on. This could break backward compatibility — it means that user-defined classes that mixin Enumerable are now responsible for handling the context themselves.

    This isn't a big deal, considering before 1.6 we didn't have a context argument at all. But what's the value of the patch in the first place? (Not arguing against it; just curious.)

  • Andrew Dupont

    Andrew Dupont February 22nd, 2009 @ 05:35 AM

    • Milestone changed from 1.6.1 to 1.7
  • Juriy Zaytsev

    Juriy Zaytsev February 22nd, 2009 @ 06:08 PM

    Andrew,

    I don't see how this can break back-compat. If user mixes Enumerable in, and defines _each the old way (without context), the context is simply undefined and an iterator is called within a global context (just as if context was not provided at all).

    We simply move responsibility to define context from each to _each (since native forEach that we use as Array#_each already takes care of a context)

    What makes sense to me is that Enumerable#each no longer controls which arguments are being passed to underlying each. It only provides a try/catch wrapper around each and _each is free to decide what to increment on every step, how to increment it, etc.

  • Samuel Lebeau

    Samuel Lebeau February 23rd, 2009 @ 12:59 AM

    @Juriy

    Just as you patched Range.prototype._each, all custom _each implementations would have to be patched to handle context argument otherwise it would have no effect at all.

    This clearly breaks back-compat, but is it a big deal ?

  • Yaffle

    Yaffle April 15th, 2009 @ 11:04 AM

    May be, Enumerable shoule have forEach method, And for back compact. keep "each"?

  • Yaffle

    Yaffle April 15th, 2009 @ 11:20 AM

    And patching Array.prototype don't breaks back-compact. (except you write function,that uses undefined arguments)

    
      function each(iterator, context) {
        for (var i = 0, length = this.length; i < length; i++)
          iterator.call(context, this[i], i , this);
      }
      if (!_each) {
        _each = each;
        arrayProto.forEach = each;
      }
    
  • Yaffle

    Yaffle April 15th, 2009 @ 11:27 AM

    And for Enumerable:

    
    var Enumerable = (function() {
      function each(iterator, context) {
        var index = 0;
        try {
    	  if(this.forEach){                 //added
    	    this.forEach(iterator, context);//added
    	  }else{
            this._each(function(value) {
              iterator.call(context, value, index++);
            });
    	  }
        } catch (e) {
          if (e != $break) throw e;
        }
        return this;
      }
    

    P.S. sorry for the flood

  • Yaffle

    Yaffle May 25th, 2009 @ 05:22 PM

    Are these changes planned for 1.7?

  • Yaffle

    Yaffle October 21st, 2009 @ 01:13 PM

    • Tag changed from patched, tested to patched

    this patch should check for index in array to fix https://prototype.lighthouseapp.com/projects/8886/tickets/790-each-...

  • T.J. Crowder

    T.J. Crowder November 16th, 2009 @ 04:50 PM

    • Assigned user cleared.

    [responsible:none bulk edit command]

  • Radoslav Stankov

    Radoslav Stankov March 2nd, 2010 @ 09:50 AM

    • Tag changed from patched to patched, section:lang
  • Arthur Schreiber

    Arthur Schreiber March 11th, 2010 @ 10:36 AM

    • Tag changed from patched, section:lang to benchmarked, patched, section:lang

    This change yields a considerable performance improvement throughout the whole library, especially in browsers that do implement a native Array#foreach method. Breaking backwards compatibility seems somewhat justified. :)

    Benchmark results for the Array#each method can be found at http://gist.github.com/328990.

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

The Prototype JavaScript library.

Shared Ticket Bins

Attachments

Pages