Подтвердить что ты не робот

Есть ли у JavaScript экзотические объекты?

Я хочу написать серию статей/учебников, связанных с JavaScript. Я искал спецификацию ECMA, когда обнаружил этот интересный абзац.

Как указано в ECMA-262 (версия 6):

4.3.7 экзотический объект

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

ПРИМЕЧАНИЕ. Любой объект, который не является обычным объектом, является экзотическим объектом.

Теперь мне любопытно. Есть ли такие экзотические объекты в современном браузере JavaScript?

Если да: мог ли я привести пример и сказать, насколько его поведение отличается от обычных объектов?

4b9b3361

Ответ 1

Возможный пример:

Объекты экземпляра, созданные Array, являются экзотическими (термин, используемый спецификацией ECMAScript для объектов, которые имеют объекты, которые не имеют обычных объектов): их длина свойства отслеживает и влияет на управление элементами массива. В общем, экзотические объекты могут создаваться с нуля, но вы не можете преобразовать существующий нормальный объект в экзотический.

Взято из http://www.2ality.com/2015/02/es6-classes-final.html

Там также список позже в спецификации, включая Array, String и т.д.

Они не "экзотичны" в смысле таинственных и/или сексуальных.

Ответ 2

В разделе 9.4 того же документа перечислены экзотические объекты. Например, массив является таким объектом. Помимо всего прочего, внутренний метод [[DefineOwnProperty]] отличается от стандартного метода, определенного для объектов тем, что он обрабатывает числовые "ключи" по-разному.

Ответ 3

массивы DOM и Array

если вы попытаетесь в браузере document.getElementsByTagName('*'), результат выглядит как объект Array, содержащий все элементы DOM, соответствующие вашему запросу. Но в этом массиве вы не можете назвать большинство функций Array, поскольку это не действительно массив.

вот пример:

var normalArray = [{objectId: 1}, {objectId: 2}, {objectId: 3}, {objectId: 4}];
var domArray = document.getElementsByTagName('*');

log(normalArray.length + ' objects in normalArray');
log(domArray.length + ' objects in domArray');
printArray(normalArray);
printArray(domArray);

function printArray(array){
  // lets try with array
  try{
    log('printing normalArray');
    array.forEach(function(data, index){
      log('Iteration on ' + index + ' ok', 'success');  
    });
  }catch(e){
    log('failed because of ' + e, 'error');
  }
}

function log(msg, className){
  var logEl = document.createElement('pre');
  logEl.innerText = msg;
  logEl.className = className || '';
  document.getElementById('logs').appendChild(logEl);
}
pre{
  background: #eee;
  padding: 3px;
  margin: 1px;
  border-radius: 3px;
}

pre.error{
  background: #fdd;
}

pre.success{
  background: #dfd;
}
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>some test</title>
	</head>
	<body>
		<h1>title</h1>
		<p>
			Some texts with some <a href="#">links</a>
		</p>
      
        <div id="logs"></div>
	</body>
</html>