问题 JavaScript有异国情调的对象吗?


我想写一系列与JavaScript相关的文章/教程。我发现时,我正在查看ECMA规范 这个 有趣的段落。

正如ECMA-262(第6版)所述:

4.3.7异国情调的对象

对于所有对象必须支持的一个或多个基本内部方法没有默认行为的对象

注意任何不是普通对象的对象都是异域对象。

现在我很好奇。在现代浏览器的JavaScript中是否可以找到这些奇特的物体?

如果是这样的话:能不能给我一个例子并说明它的行为与“普通物体”有多远?


1211
2017-07-29 19:11


起源

在DOM API主机领域, HTMLElement.dataset.prototype object具有魔法getter和setter,其行为与普通对象不同。 - Awal Garg
的document.all - Knu


答案:


一个可能的例子:

由Array创建的实例对象是异国情调的(ECMAScript规范用于具有普通对象没有的特征的对象的术语):它们的属性长度跟踪并影响数组元素的管理。通常,可以从头开始创建奇异物体,但不能将现有的普通物体转换为异国物体。

取自 http://www.2ality.com/2015/02/es6-classes-final.html

规范的后面还有一个列表,包括Array,String等。

它们在神秘和/或性感的意义上并非“异国情调”。


11
2017-07-29 19:18



什么是“普通物体没有的特征”是什么意思?最后有一些内置代码(例如:对于数组的长度轨道),普通对象可以有。 - Mehdi Raash
@Vandaad 可以 有,是的。虽然length 不只是跟踪长度。例如。, stackoverflow.com/a/31550694/438992,并从规范:“异国情调的对象是任何形式的对象,其属性语义与默认语义有任何不同。”我认为人们在阅读“异国情调”这个词时已经过多了。 - Dave Newton
我刚读过这篇文章 Bound Functions  developer.mozilla.org/en/docs/Web/JavaScript/Reference/...  - 这些也是异国情调的对象。出于兴趣,我们还可以说这些对象是 Tropical 和 Temperate? - Luke T O'Brien


第9.4节 同一文件列出了异国情调的物品。例如,数组就是这样的对象。除其他外,它是 [[DefineOwnProperty]] 内部方法不同于为对象定义的标准方法,因为它以不同方式处理数字“键”。


4
2017-07-29 19:17



没有评论解释它的-1有什么意义? - Amit
为了概述该部分中的类型,可以识别以下外来对象类型:绑定函数,数组,字符串,参数,索引的整数(显然与数组缓冲区相关),模块命名空间和代理。更长的摘要如下: quora.com/... - Brett Zamir


DOM数组与数组

如果您尝试在浏览器中 document.getElementsByTagName('*') 结果看起来是一个Array对象,其中包含与查询匹配的所有DOM元素。但是在那个阵列上你不能调用大多数阵列功能,因为它不是一个真正的阵列。

这是一个例子:

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>


1
2017-07-29 19:39



这个片段有什么意义?你想说的吗? domArray 是异国情调,因为它没有 forEach 功能定义? (提示:这不是普通对象的“要求”) - Amit
getElementsByTagName 和类似的方法返回一个 NodeList,而不是数组。 - Lesleh
我猜错了这个定义,我们可以定义 essential internal methods 那么,我也想知道。 - zeachco