Javascript-форум (https://javascript.ru/forum/)
-   Оффтопик (https://javascript.ru/forum/offtopic/)
-   -   Array.prototype.copyWithin (https://javascript.ru/forum/offtopic/45987-array-prototype-copywithin.html)

Octane 23.03.2014 17:14

Array.prototype.copyWithin
 
Не пойму, для чего нужен метод copyWithin?
http://people.mozilla.org/~jorendorf...ype.copywithin

monolithed 23.03.2014 18:49

Хм.

describe('Array#copyWithin', function() {
      it('has the right arity', function() {
        expect(Array.prototype.copyWithin.length).to.equal(2);
      });

      it('works with 2 args', function() {
        expect([1, 2, 3, 4, 5].copyWithin(0, 3)).to.eql([4, 5, 3, 4, 5]);
        expect([1, 2, 3, 4, 5].copyWithin(1, 3)).to.eql([1, 4, 5, 4, 5]);
        expect([1, 2, 3, 4, 5].copyWithin(1, 2)).to.eql([1, 3, 4, 5, 5]);
        expect([1, 2, 3, 4, 5].copyWithin(2, 2)).to.eql([1, 2, 3, 4, 5]);
      });

      it('works with 3 args', function() {
        expect([1, 2, 3, 4, 5].copyWithin(0, 3, 4)).to.eql([4, 2, 3, 4, 5]);
        expect([1, 2, 3, 4, 5].copyWithin(1, 3, 4)).to.eql([1, 4, 3, 4, 5]);
        expect([1, 2, 3, 4, 5].copyWithin(1, 2, 4)).to.eql([1, 3, 4, 4, 5]);
      });

      it('works with negative args', function() {
        expect([1, 2, 3, 4, 5].copyWithin(0, -2)).to.eql([4, 5, 3, 4, 5]);
        expect([1, 2, 3, 4, 5].copyWithin(0, -2, -1)).to.eql([4, 2, 3, 4, 5]);
        expect([1, 2, 3, 4, 5].copyWithin(-4, -3, -2)).to.eql([1, 3, 3, 4, 5]);
        expect([1, 2, 3, 4, 5].copyWithin(-4, -3, -1)).to.eql([1, 3, 4, 4, 5]);
        expect([1, 2, 3, 4, 5].copyWithin(-4, -3)).to.eql([1, 3, 4, 5, 5]);
      });

      it('works with arraylike objects', function() {
        var args = (function () { return arguments; }(1, 2, 3));

        expect(Array.isArray(args)).not.to.be.ok;

        var argsClass = Object.prototype.toString.call(args);
        expect(Array.prototype.slice.call(args)).to.eql([1, 2, 3]);

        Array.prototype.copyWithin.call(args, -2, 0);

        expect(Array.prototype.slice.call(args)).to.eql([1, 1, 2]);
        expect(Object.prototype.toString.call(args)).to.equal(argsClass);
      });
    });


copyWithin: function(target, start) {
        var end = arguments[2]; // copyWithin.length must be 2
        var o = ES.ToObject(this);
        var len = ES.ToLength(o.length);

        target = ES.ToInteger(target);
        start = ES.ToInteger(start);

        var to = target < 0 ? Math.max(len + target, 0) : Math.min(target, len);
        var from = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);

        end = (end===undefined) ? len : ES.ToInteger(end);

        var fin = end < 0 ? Math.max(len + end, 0) : Math.min(end, len);
        var count = Math.min(fin - from, len - to);
        var direction = 1;

        if (from < to && to < (from + count)) {
          direction = -1;
          from += count - 1;
          to += count - 1;
        }

        while (count > 0) {
          if (_hasOwnProperty.call(o, from)) {
            o[to] = o[from];
          }
          else {
            delete o[from];
          }

          from += direction;
          to += direction;
          count -= 1;
        }

        return o;
}

Octane 23.03.2014 18:56

Не ну найти реализацию и посмотреть результаты я в состоянии. Меня интересует зачем кому-то так часто требовались такие преобразования массива, чтобы добавлять метод в спецификацию. Не могу придумать применения.

monolithed 23.03.2014 19:06

А ты об этом, я тоже в недоумении ;)

Octane 23.03.2014 19:53

Переписал пример реализации выше без лишних проверок в надежде понять нафиг это нужно
if (!Array.prototype.copyWithin) {
	Array.prototype.copyWithin = function(target, start, end) {
		var length = this.length, count, direction,
			to = target < 0 ? Math.max(length + target, 0) : Math.min(target, length),
			from = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
		end = typeof end == "undefined" ? length : end;
		end = end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
		count = Math.min(end - from, length - to);
		direction = 1;
		if (from < to && to < (from + count)) {
			direction = -1;
			from += count - 1;
			to += count - 1;
		}
		while (count > 0) {
			if (from in this) {
				this[to] = this[from];
			}
			else {
				delete this[from];
			}
			from += direction;
			to += direction;
			count -= 1;
		}
		return this;
	};
}

alert([

	[1, 2, 3, 4, 5].copyWithin(0, 3).toString() == [4, 5, 3, 4, 5].toString(),
	[1, 2, 3, 4, 5].copyWithin(1, 3).toString() == [1, 4, 5, 4, 5].toString(),
	[1, 2, 3, 4, 5].copyWithin(1, 2).toString() == [1, 3, 4, 5, 5].toString(),
	[1, 2, 3, 4, 5].copyWithin(2, 2).toString() == [1, 2, 3, 4, 5].toString(),

	[1, 2, 3, 4, 5].copyWithin(0, 3, 4).toString() == [4, 2, 3, 4, 5].toString(),
	[1, 2, 3, 4, 5].copyWithin(1, 3, 4).toString() == [1, 4, 3, 4, 5].toString(),
	[1, 2, 3, 4, 5].copyWithin(1, 2, 4).toString() == [1, 3, 4, 4, 5].toString(),

	[1, 2, 3, 4, 5].copyWithin(0, -2).toString()      == [4, 5, 3, 4, 5].toString(),
	[1, 2, 3, 4, 5].copyWithin(0, -2, -1).toString()  == [4, 2, 3, 4, 5].toString(),
	[1, 2, 3, 4, 5].copyWithin(-4, -3, -2).toString() == [1, 3, 3, 4, 5].toString(),
	[1, 2, 3, 4, 5].copyWithin(-4, -3, -1).toString() == [1, 3, 4, 4, 5].toString(),
	[1, 2, 3, 4, 5].copyWithin(-4, -3).toString()     == [1, 3, 4, 5, 5].toString(),

].every(function (testResult) {
	return testResult;
}));

monolithed 23.03.2014 20:12

Цитата:

Сообщение от Octane
в надежде понять нафиг это нужно

Если ты понял расскажи, а я тоже не вкурю зачем это нужно в стандарте :D

Octane 23.03.2014 21:21

думаю базовые 2 случая copyWithin(0, 1) и copyWithin(1, 0), а остальное потом накрутили

[1, 2, 3, 4, 5].copyWithin(0, 1)
       ↓
[2, 3, 4, 5, 5].copyWithin(0, 1)
       ↓
[3, 4, 5, 5, 5].copyWithin(0, 1)
       ↓
[4, 5, 5, 5, 5].copyWithin(0, 1)
       ↓
[5, 5, 5, 5, 5].copyWithin(0, 1)



[1, 2, 3, 4, 5].copyWithin(1, 0)
       ↓
[1, 1, 2, 3, 4].copyWithin(1, 0)
       ↓
[1, 1, 1, 2, 3].copyWithin(1, 0)
       ↓
[1, 1, 1, 1, 2].copyWithin(1, 0)
       ↓
[1, 1, 1, 1, 1].copyWithin(1, 0)


похоже на shift и unshift без изменения длины

monolithed 24.03.2014 00:45

С трудом могу представить практическую ценность данного метода.

nerv_ 25.03.2014 00:04

Цитата:

Сообщение от Octane
Не пойму, для чего нужен метод copyWithin

кто-то по блату пролоббировал :D


Часовой пояс GMT +3, время: 03:49.