Skip to content
This repository
Browse code

* forEach / else pseudo implementation

  • Loading branch information...
commit a3f2be40c6bab00989463d47ec3df37ceebcef20 1 parent 5825321
Julien Polo authored October 12, 2011
42  stj.js
@@ -278,6 +278,13 @@
278 278
             },
279 279
 
280 280
             /**
  281
+             * Shortcut to freeze
  282
+             */
  283
+            freeze = Object.freeze || function (e) {
  284
+                return e;
  285
+            },
  286
+
  287
+            /**
281 288
              * Return an array of keys for obj
282 289
              */
283 290
             objectKeys = (function /*factory*/() {
@@ -311,9 +318,18 @@
311 318
             returnGet = function (args, defaultValue) {
312 319
                 return getOwn(args, '__return__', defaultValue);
313 320
             },
  321
+            forEachBreaked = freeze({
  322
+                end: function () {}
  323
+            }),
  324
+            forEachEnd = freeze({
  325
+                end: function (callback, thisp) {
  326
+                    callback.call(thisp);
  327
+                }
  328
+            }),
314 329
             forEach = function forEach(obj, iterator/*, thisp, options */) {
315 330
                 var key,
316  
-                    thisp = arguments[2];
  331
+                    thisp = arguments[2],
  332
+                    breaked = false;
317 333
                 validateFunction(iterator);
318 334
                 if (obj) {
319 335
                     try {
@@ -330,10 +346,13 @@
330 346
                     } catch (e) {
331 347
                         if (!(e instanceof StopIteration)) {
332 348
                             throw e;//rethrow
  349
+                        } else {
  350
+                            breaked = true;
333 351
                         }
334 352
                     }
335 353
                 }
336  
-                return returnGet(thisp, obj);
  354
+                return  hasOwn(thisp, '__return__') ? thisp.__return__:
  355
+                        breaked ? forEachBreaked : forEachEnd;
337 356
             },
338 357
 
339 358
             /**
@@ -727,9 +746,6 @@
727 746
                 return moduleObject;
728 747
             },
729 748
 
730  
-
731  
-
732  
-
733 749
             //=========================================================================
734 750
             //                                Class
735 751
             //=========================================================================
@@ -1842,6 +1858,19 @@
1842 1858
                 /**
1843 1859
                  * Iterate on object.
1844 1860
                  * Call internal object.__forEach__(iterator, thisp, options) if exists.
  1861
+                 * Return the thisp.__return__ if defined else returns an method
  1862
+                 *
  1863
+                 * Example:
  1864
+                 *
  1865
+                 * Object
  1866
+                 * .forEach(['foo', 'bar', 'baz'], function (value) {
  1867
+                 *     console.log(value);
  1868
+                 * })
  1869
+                 * .end(function () {
  1870
+                 *     //if no StopIteration were thrown
  1871
+                 *     console.log('notbreaked');
  1872
+                 * }, thisp);
  1873
+                 *
1845 1874
                  *
1846 1875
                  * @param {*} obj
1847 1876
                  * @param {Function} iterator
@@ -2656,7 +2685,8 @@
2656 2685
                             objectUnset(self, key);
2657 2686
                         };
2658 2687
                         return function clear() {
2659  
-                            return objectForEach(this, iterator);
  2688
+                            objectForEach(this, iterator);
  2689
+                            return this;
2660 2690
                         };
2661 2691
                     }()),
2662 2692
 
25  test/object-test.js
@@ -496,6 +496,31 @@ exports.ObjectTest = vows.describe('Object functions').addBatch({
496 496
             assert.throws(function () {
497 497
                 topic(null, 'nonfunction');
498 498
             }, TypeError);
  499
+        },
  500
+        'should stop iteration when StopIteration is thrown': function (topic) {
  501
+            var last;
  502
+            topic(['foo', 'bar'], function (value, _, self) {
  503
+                last = value;
  504
+                self.stopIteration();
  505
+            });
  506
+            assert.equal(last, 'foo');
  507
+        },
  508
+        'should an object {end: [Function]} that will called only if not breaked': function (topic) {
  509
+            var breaked = false;
  510
+            topic(['foo', 'bar'], function (value, _, self) {
  511
+
  512
+            }).end(function () {
  513
+                breaked = true;
  514
+            });
  515
+            assert.equal(breaked, true);
  516
+
  517
+            breaked = false;
  518
+            topic(['foo', 'bar'], function (value, _, self) {
  519
+                self.stopIteration();
  520
+            }).end(function () {
  521
+                breaked = true;
  522
+            });
  523
+            assert.equal(breaked, false);
499 524
         }
500 525
     },
501 526
     "map()": {

0 notes on commit a3f2be4

Please sign in to comment.
Something went wrong with that request. Please try again.