我检查了在窗口全局对象中定义的属性的名称,但是我看不到任何与上述名称匹配的属性(字符串,parseInt等)。下面是我用来查找属性的JS代码:
<script type="text/javascript">
for(var prop in window){
document.write(prop + '\n');
}
</script>
编辑: 基于以下注释,我做了一个控制台日志,并打印:ƒString(){[native code]}。
这提出了另一个问题。当我在脚本中定义函数时,可以通过使用代码找到与该函数名称同名的属性。那么这些强制转换函数(Number(),String())有什么特别之处,当我使用for-in枚举时我看不到它们。
这些强制转换函数是否以不同的语法编写,以某种方式无法枚举?
答案 0 :(得分:4)
for...in
仅迭代可枚举属性。您想找到的那些可能无法枚举。只需
console.log(window.String);
但是,关于它们的定义的更多信息:
它们是在全局环境中定义的。环境基本上是一个将名称与 values 相关联的映射,也称为 bindings (值绑定到名称)。例如,给出以下代码:
var foo = 42;
var bar = "abc";
在评估此代码时创建的环境看起来像
+-------------+
| foo | 42 |
|-----|-------|
| bar | "abc" |
+-------------+
JavaScript具有两种基本类型的环境:声明性环境和对象环境。
无法直接访问声明性环境,例如没有可引用的值可以对其所有条目进行迭代。声明性环境的一个示例是函数环境,即调用函数时创建的环境。无法遍历函数内部声明的所有变量。
对象环境是由普通对象“支持”的环境。这意味着绑定不是以某种方式在内部存储,而是实际上是该对象的属性。
全局环境就是这样一种环境,它(部分地)由全局对象支持,该全局对象在浏览器中为window
。这就是内置的全局绑定也是全局对象的属性的原因。
您可以找到所有内置全局绑定in the specification的列表。
话虽如此,全局对象对于全局环境工作/存在或内置全局变量不是必需的。所有这些都是在创建全局环境时简单创建的(因为规范这样说)。您也可以访问这些值,而无需通过全局对象:
console.log(String);
那么这些转换函数(Number(),String())有什么特别之处,当我使用for-in枚举时我看不到它们。
The specification simply says that these built-in global values should not be enumerable:
除非另有说明,否则第18至26条和附件B.2中描述的所有其他数据属性都具有属性
{ [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }
。
这些强制转换函数是否以不同的语法编写,以某种方式无法枚举?
好吧,这些功能大多数是用本机代码(例如C ++)实现的,而不是用JavaScript实现的。但是,这并不是使它们不可枚举的原因。每个属性都有与其关联的一堆标志,其中一个是enumerable
标志。通常情况下,创建属性时不会被这些标志所困扰,它们只有一些默认值。
但是您可以轻松创建不可枚举的属性,例如与Object.defineProperty
:
var obj = {};
Object.defineProperty(obj, 'foo', {value: 42, enumerable: false});
console.log(obj.foo);
for (var prop in obj) console.log(prop);