Javascript-форум (https://javascript.ru/forum/)
-   ExtJS (https://javascript.ru/forum/extjs/)
-   -   Как сделан Array.forEach() ? (https://javascript.ru/forum/extjs/55956-kak-sdelan-array-foreach.html)

khusamov 22.05.2015 17:23

Как сделан Array.forEach() ?
 
Пытался найти текст кода, где реализован Array.forEach()

http://docs.sencha.com/extjs/5.1/5.1...method-forEach

И не нашел. Они как-то сделали, что в для каждого массива доступны дополнительные методы. Хочу посмотреть как они это реализовали. Мне нужно туда добавить парочку, только для класса Number.

novikov 22.05.2015 17:45

http://docs.sencha.com/extjs/5.1/5.1...ay-method-each

про нативный Array нужно поискать...

forEach: ('forEach' in arrayPrototype) ? function(array, fn, scope) {
                return array.forEach(fn, scope);
            } : function(array, fn, scope) {
                for (var i = 0,
                    ln = array.length; i < ln; i++) {
                    fn.call(scope, array[i], i, array);
                }
            },

khusamov 22.05.2015 17:46

Попробовал вот так, вроде работает. Но помнится был неудачный опыт, хотелось бы посмотреть как это делают профи.

Ext.define("MyNumber", {
		
		override: "Number",
		
		unit: null,
		
		setUnit: function(unit) {
			this.unit = unit;
			return this;
		},
		
		getUnit: function() {
			return this.unit;
		},
		
		toString: function(withUnit) {
			return withUnit ? String(this) + " " + this.unit : this;
		}
		
	});
	
	
	console.log((5).setUnit("мм").toString(true));

novikov 22.05.2015 18:49

Изменять прототипы нативных объектов чревато конфликтами библиотек, поэтому я думаю, что Сенча не меняли ничего, а просто добавили в документацию описание того, что есть в JS, для полноты картины и чтобы знать свой набор инструментов. Может, метод forEach есть во всех поддерживаемых браузерах? Могу ошибаться.

Ну и у нативного объекта нельзя найти метод callParent. Ext.define на этом ломается, предположительно.

khusamov 22.05.2015 20:11

Я считал что операция Ext.override как раз и добавляет метод callParent...

По поводу того, что forEach штатная функция JS я не подумал. Надо проверить это дело... у меня чето застарелый мануал по JS тогда.

nohuhu 22.05.2015 21:20

Array.forEach() это нативный метод в IE9+ и прочих ES 5.1 совместимых браузерах. Ext JS не добавляет polyfill в IE8, а вместо этого предоставляет отдельный объект Ext.Array, в котором forEach либо проваливается в нативный, если такой метод есть, или выполняется нашим кодом. Своего рода polyfill, но без мусора в нативных прототипах.

Ext.define({ override: … }) работает только на классах, которые наследуются от Ext.Base. Любой класс, заданный с помощью Ext.define(), наследуется от Ext.Base, но нативные объекты конечно же такого наследования не имеют, поэтому сделать override нативного объекта не получится.

khusamov 23.05.2015 00:15

Спасибо про Ext.Base, понял откуда берется метод callParent()...

Правда пока сам оверрайд работает, как ни странно. Разве что придется обходится без callParent...

nohuhu 23.05.2015 00:35

"Работает" это растяжимое понятие. Ext.override(), или Ext.define({ override: … }) "просто" заменит старые свойства объекта на новые, точно так же, если их руками присвоить. Но будет ли это работать так, как вы ожидаете? Зависит от ожиданий. ;)

Вот вы пример хороший сами же привели, что callParent() работать не будет. Так и не будет, откуда ссылке на суперкласс взяться в нативном объекте?

И таки да, ничего особенно волшебного в классовой системе Ext JS нету. Берём объекты JavaScript, шаманим с прототипами и вуаля. Просто если делать всё это каждый раз руками, то руки быстро отвалятся.


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