Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #21 (permalink)  
Старый 07.04.2020, 20:10
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от voraa
Вы, наверно, чего то не знаете
Знаю, но это с ECMAScript 5, а в РНР это было всегда. Поэтому глубоко рассуждать о том, что принято как понятие/термин, какой смысл.
Ответить с цитированием
  #22 (permalink)  
Старый 07.04.2020, 20:25
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,744

Сообщение от laimas Посмотреть сообщение
Поэтому глубоко рассуждать о том, что принято как понятие/термин, какой смысл.
Ну просто это определение языка. Его синтаксис и семантика.

https://www.ecma-international.org/e...9.0/index.html

Определяется понятие объекта. Определяется, что имена свойства объекта - строки. Вводится понятие "целочисленного индекса" причем для обычных объектов тоже. Но говорится, что это все равно строка

6.1.7
Properties are identified using key values. A property key value is either an ECMAScript String value or a Symbol value. All String and Symbol values, including the empty string, are valid as property keys. A property name is a property key that is a String value.

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.

А дальше добавляется некоторая "экзотика" для объектов Аrray, Snring, Function...
Но нигде не говорится, что индекс массива, это что то иное, чем свойство объекта, заданного строкой.

Вообще разгвор (мой пост) начался с того, почему не сделать в javascript отрицательные "индексы" у массивов.
Потому, что они уже есть. Но у них другая семантика. А менять семантику того, что уже есть, и быть может, как то кем то используется - низя!

Последний раз редактировалось voraa, 07.04.2020 в 20:33.
Ответить с цитированием
  #23 (permalink)  
Старый 07.04.2020, 21:55
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Экзотика, не экзотика, но индекс определен, это ни какое-то эфемерное понятие. )

А если углубляться и для различных языков, то "Чем обычный объект не ассоциативный массив?" в JS, это нечто приближенное, а в РНР именно ассоциативный массив. А если привести его к объекту, то работать с ним как с массивом уже не получится. В js можно и так object.property, и так object[property], а вот в РНР с объектом только так object->property, а так object[property], это фатальная ошибка.
Ответить с цитированием
  #24 (permalink)  
Старый 08.04.2020, 00:53
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,744

Сообщение от laimas Посмотреть сообщение
Экзотика, не экзотика, но индекс определен, это ни какое-то эфемерное понятие. )
А какое? Чем оно отличается от имени свойства?
Ну в С или каком другом языке это можно понять как номер элемента в последовательности, расположенной в памяти.

А если так
let a = [];
a[0]=0; a[1]=1; a[3]=3;

console.log(a[2]); // undefined ну нет элемента, так чего с него взять.

А если так
Array.prototype['2']=2;
let a = [];
a[0]=0; a[1]=1; a[3]=3;

console.log(a[2]); // 2! Ух ты! Так его же нет!
И получается, что массив ведет себя как голимый объектишко.
И когда нет элемента с индексом, он зачем то лезет в прототип. Прототип то объект - у него нет индексов, а только свойства с именами. А наш массив зачем то вместо индекса лезет за свойством по его имени.
Да просто индексы - это всего лишь имена (строковые) свойств.
Ответить с цитированием
  #25 (permalink)  
Старый 08.04.2020, 04:49
Аватар для Белый шум
Профессор
Отправить личное сообщение для Белый шум Посмотреть профиль Найти все сообщения от Белый шум
 
Регистрация: 19.01.2012
Сообщений: 505

Сообщение от voraa
В javascript вообще нет такого понятия, как индекс массива.
Сообщение от voraa
Да просто индексы - это всего лишь имена (строковые) свойств.
Так есть понятие или нету? А то я запутался
Ответить с цитированием
  #26 (permalink)  
Старый 14.04.2020, 02:16
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от Белый шум
Так есть понятие или нету? А то я запутался
Если в спецификации говорится об индексах, то понятие определённо есть!

Сообщение от Aetae
Если вы шизофреник, то это ваши проблемы.
Сообщение от jaroslav.tavgen
а по сути скажу то, что наличие метода... подсказывало бы новичкам, что существует и метод lastIndexOf, наличие которого зачастую является сюрпризом.
Например, для меня было очевидно, что такие методы должны уметь работать и «вперёд» и «назад». Поэтому когда я узнал про indexOf, то я практически сразу узнал про lastIndexOf, когда задался вопросом, а как то же самое сделать с конца строки. (Тоже самое было с методами списка reduce и reduceRight и пр.)

Сообщение от jaroslav.tavgen
наличие метода firstIndexOf подсказывало бы новичкам, что существует и метод lastIndexOf
Совершенно не логично — оно скорей подсказывало бы, что если есть firstIndexOf, то должен быть и secondIndexOf и thirdIndexOf и...

Сообщение от voraa
В javascript вообще нет такого понятия, как индекс массива.
Все объекты (включая и списки — экземпляры класса Array) в JS наследуют от класса Object, а значит они все похожи на экземпляры класса Object. Однако дальнейшее наследование позволяет описать более подробно структуры данных, а это значит, что у списков могут быть описаны индексы. (Согласно спецификации, объекты списка — это такие объекты, которые обеспечивают особую обработку определенному классу имён свойств — включая целочисленные индексы списка, числовое значение i которых находится в диапазоне +0 ≤ i < 2³² − 1. https://tc39.es/ecma262/#sec-array-exotic-objects)

Т. е. вы можете обработать отдельно и собственные свойства списка как объекта и индексы списка.

var xs = [1,2,3];
xs["1.5"] = 15;
xs["-1"] = -1;

console.group("собственные свойства списка как объекта");

for(const [key, value] of Object.entries(xs)) {
	console.log("свойство:", key, "значение:", value);
}

console.groupEnd();

console.group("индексы списка");

for(const [index, element] of xs.entries()) {
	console.log("индекс:", index, "элемент:", element);
}

console.groupEnd();


var a = [];
a[15] = "⛵";
a[4371813261] = "⛴";
alert(a.length); // 16


Сообщение от voraa
Единственная экзотичность объекта Array связана с обработкой свойства length.
Ложь! Таких свойств — 4294967296. Свойство length, а также целочисленные индексы от 0 до 4294967294. Т. е. если вы возьмёте 4294967295 или большее целое число, то это число не будет являться индексом списка и не будет влиять на длину списка. См. пример выше.

Сообщение от voraa
Чем обычный объект не ассоциативный массив?
Это частный случай ассоциативного массива — когда ключами могут являться строки (числа приводятся к их строковому представлению) и символы. (а не любые типы данных)

Сообщение от laimas
А если углубляться и для различных языков, то "Чем обычный объект не ассоциативный массив?" в JS, это нечто приближенное, а в РНР именно ассоциативный массив.
В РНР — это только частично ассоциативный массив, т. е. его ключи ограничены типом строка, что означает, что он ничем не отличается от экземпляра класса Object в JS. (объект в JS мощней, поскольку ключами могут быть ещё и представители типа Symbol)

Ассоциативный массив — это такой тип данных — коллекция, состоящая из таких пар (ключ, значение) — что всевозможные ключи представлены в ней только один раз.

Смотрим в PHP, разные ключи 5 и "5" не могут быть представлены в так называемом «ассоциативном массиве», а значит — это не настоящий ассоциативный массив.
<?php

$a = [
	5 => "Hi, guys!",
	"5" => "Hi, y’all!"
];

echo json_encode([
	length => count($a),
	keys => array_keys($a),
	elements => array_values($a)
], JSON_PRETTY_PRINT);


Запускаем...
Код:
~ via 🐘 v7.0.33 
➜ curl "http://(:1):5000/aa.php"
{
    "length": 1,
    "keys": [
        5
    ],
    "elements": [
        "Hi, y’all!"
    ]
}%
Отличие в том, что в PHP неправильно названа структура типа «коллекция пар (строка, значение)», это явно не ассоциативный массив. Эта структура скорей соответствует тому, что было в ECMAScript 3 и называлось объектом. (но только, опять же, частично!)

Ассоциативный массив реализован, например, в C# — Dictionary, Java — HashMap, JavaScript — Map.

Сообщение от voraa
А какое? Чем оно отличается от имени свойства?
Ну в С или каком другом языке это можно понять как номер элемента в последовательности, расположенной в памяти.
Сообщение от voraa
И получается, что массив ведет себя как голимый объектишко.
Так если сравнивать, то следует сравнивать подобные вещи! Например массив в C имеет конкретную длину, которая указывается при его инициализации, массив заполняется нулями, а затем вы можете указать конкретные элементы, как вы это делали тут в примере. (в JS это TypedArray)

var a = new Float64Array(4);

console.log(a); // массив заполнен нулями

// изменяем массив
a[0]=0; a[1]=1; a[3]=3;

console.log(a[2]); // 0, а вы ожидали что-то другое?


Сообщение от voraa
Прототип-то объект — у него нет индексов, а только свойства с именами. А наш массив зачем то вместо индекса лезет за свойством по его имени.
Экземпляры класса Array не используют никакую отдельную область памяти для хранения (как это делают типизированные массивы, см. пример выше), свойства, представленные целыми числами от 0 до 4294967294 включительно хранятся как и все остальные свойства объекта типа Array — именно как свойства, поэтому если вы напишете Array.prototype[2] = 2 или наоборот что-то не объявите, вы получите точно такой же результат, как если бы работали с экземпляром класса Object.

Однако именно свойства, представленные целыми числами от 0 до 4294967294 означают индексы списка, по которым можно получить соответствующие элементы списка. Все методы списка работают именно с индексами.

Рассмотрим ещё пару примеров с вашим списком...
var xs = [1,2,3];
xs["1.5"] = 15;
xs["-1"] = -1;

// элементы списка можно получить по индексам
alert(JSON.stringify(xs));


var a = new Array(4);

console.log(a); // список ничем не заполнен [empty × 4]

// изменяем список
a[0]=0; a[1]=1; a[3]=3;

console.log(a); // [0, 1, empty, 3]


// только для voraa, если вам нужен массив с предопределёнными
// значениями, то используйте наследование от класса Array
Array.prototype[2] = 2;
Array.prototype[20] = 20;

var a = new Array(4);

console.log(a); // список ничем не заполнен [empty × 4]
/*

Однако на самом деле теперь индексы 2 и 20 есть у всех массивов,
однако инициализируя массив при помощи [] или new Array(4),
свойство length определяется на самом списке (у каждого списка своя длина)

{
	length: 4,
	__proto__: {
		"2": 2,
		"20": 20,
		length: 21,
		constructor: Array,
		// остальные методы и свойства
		__proto__: {
			constructor: Object,
			// остальные методы и свойства объекта
			__proto__: null
		}
	}
}

*/

// изменяем список
a[0]=0; a[1]=1; a[3]=3;

console.log(Array.from(a)); // [0, 1, 2, 3]

// Однако ручная инициализация приводит к тому,
// что видны все элементы
console.log(({ __proto__: Array.prototype }).map(v => v)); // [empty × 2, 2, empty × 17, 20]

// Ещё пример...
var b = { __proto__: Array.prototype };
b.push(22);
console.log(b); // [empty × 21, 22]
console.log(Array.from(b)); // [undefined × 2, 2, undefined × 17, 20, 22]


Списки так работают, поскольку они не используют отдельный объект для своих элементов, что компенсируется тем, что у списков есть множество методов, что позволяет исключить прямое манипулирование индексами.

Сообщение от jaroslav.tavgen
Почему такую штуку не ввели?

Array.prototype.last = function(){
    return this[this.length-1];
}
Такой метод предполагает дополнительные проверки, получение последнего элемента, обёрнутого в контейнер (в данном случае список), позволяет почувствовать всю мощь монад! (Работает уже сегодня)
array.slice(-1).forEach(item => {
	// do something with last item
});


Вытаскивание элемента из контейнера (в данном случае список) предполагает дополнительные проверки!
const item = array.last();

if(item) {
	// do something with last item
});

Последний раз редактировалось Malleys, 14.04.2020 в 02:22. Причина: Грамматический нацист
Ответить с цитированием
  #27 (permalink)  
Старый 14.04.2020, 08:09
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

Malleys,
Ответить с цитированием
  #28 (permalink)  
Старый 14.04.2020, 09:28
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Стоило открывать дважды Америку, если и ежик знает, что массив не может содержать дубликаты ключей, как и объект дубликаты свойств, ключ/свойство примет последнее значение. А чтобы это увидеть JS совсем и не нужен.

$a = [3=> 1, '3'=> 2];
print_r($a);
print_r((object)$a);

Array
(
    [3] => 2
)
stdClass Object
(
    [3] => 2
)
Ответить с цитированием
  #29 (permalink)  
Старый 15.04.2020, 02:58
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от laimas
что массив не может содержать дубликаты ключей
Вы часто утверждаете, что в PHP есть «ассоциативные массивы», потом про ту же структуру говорите, что это «массив»... Для ассоциативного массива ключи 3 и '3' являются разными и даже с помощью PHP можно увидеть такую разницу...
Код:
➜ php --interactive
Interactive mode enabled

php > echo 3 !== '3' ? 'Это разные ключи' : 'Это одинаковые ключи';
Это разные ключи
php >
Сообщение от laimas
А чтобы это увидеть JS совсем и не нужен.
Однако стоит учитывать, что вы ранее писали, что в PHP есть «настоящие ассоциативные массивы», однако ваш последний пример как раз-таки опровергает такое понимание.

Сообщение от laimas
А чтобы это увидеть JS совсем и не нужен.
В JS как раз таки можно продемонстрировать работу ассоциативного массива...
var a = new Map();
a.set(3, 1);
a.set("3", 2);

console.log(a); // Map(2) {3 => 1, "3" => 2}
console.log(a.size); // 2

Последний раз редактировалось Malleys, 15.04.2020 в 03:32.
Ответить с цитированием
  #30 (permalink)  
Старый 15.04.2020, 03:28
Аватар для Белый шум
Профессор
Отправить личное сообщение для Белый шум Посмотреть профиль Найти все сообщения от Белый шум
 
Регистрация: 19.01.2012
Сообщений: 505

Сообщение от Malleys
Однако стоит учитывать, что вы ранее писали, что в PHP есть «настоящие ассоциативные массивы»,
Сообщение от Материал из Википедии — свободной энциклопедии
Ассоциативный массив — абстрактный тип данных (интерфейс к хранилищу данных), позволяющий хранить пары вида «(ключ, значение)» и поддерживающий операции добавления пары, а также поиска и удаления пары по ключу...

Предполагается, что ассоциативный массив не может хранить две пары с одинаковыми ключами.
Нет такого правила, что ассоциативный массив обязан различать числа от строк с этим числом. Для языков с нестрогой типизацией такое поведение является ожидаемым.

Сообщение от Malleys
однако ваш последний пример как раз-таки опровергает такое понимание.
Сообщение от Материал из Википедии — свободной энциклопедии
Поддержка ассоциативных массивов есть во многих интерпретируемых языках программирования высокого уровня, таких, как Perl, PHP, Python, Ruby, Tcl, JavaScript[1] и других.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Почему PHP в JavaScript? Chiz Общие вопросы Javascript 3 19.04.2012 21:08
Последние книги по JavaScript! monolithed Учебные материалы 7 26.10.2010 19:40
Выдвет ошибку JavaScript Ромио Opera, Safari и др. 4 21.10.2010 20:34
Помогите с javascript (Почему не работает) remus Оффтопик 9 09.06.2010 11:18
JavaScript на Яндекс.Фотки - почему тормозит браузеры? ZavFirefox Javascript под браузер 23 27.09.2009 19:24