我花了几个小时,只是找出我拼错字.length作为.lenght.它可以正常运行,完全没有警告.为什么...?
我'use strict'在Node.js 10.13.0上使用并运行.
码:
'use strict';
let arr = [1, 2, 3, 4];
for(let i = 0; i < arr.lenght; i++) {
console.log(arr[i]);
}Run Code Online (Sandbox Code Playgroud)
eag*_*845 72
因为当你试图获得一个不存在的属性时,它会返回undefined,并且0 < undefined是false.
let arr = [1, 2, 3, 4];
console.log(arr.lenght) // undefined
console.log(arr.qwerty) // undefined
console.log(arr.lenght < 9999) // false
console.log(arr.lenght > 9999) // false
arr.length = 7 // <-- it's not a good idea
for(let i = 0; i < arr.length; i++) {console.log(arr[i])}Run Code Online (Sandbox Code Playgroud)
编辑
我说'javascript不是强类型语言',这是真的.但正如@Voo所说,这种添加新属性的方式是基于原型的编程的一个特性.
我还说.length=7这是一个坏主意.在阅读了一点之后,在这种情况下,我仍然认为length在添加元素后增加属性有点奇怪.也许可以截断,删除元素或清空一个数组,尽管在后一种情况下我更愿意arr=[]而不是arr.length=0.
Mozilla文档中有一些有关length属性的有趣示例.
JavaScript数组的长度属性和数字属性是连接的.几个内置数组方法(例如,join(),slice(),indexOf()等)在调用时考虑了数组长度属性的值.其他方法(例如,push(),splice()等)也会导致更新数组的length属性.
Run Code Online (Sandbox Code Playgroud)var fruits = []; fruits.push('banana', 'apple', 'peach'); console.log(fruits.length); // 3当属性是有效的数组索引并且该索引超出数组的当前边界时,在JavaScript数组上设置属性时,引擎将相应地更新数组的length属性:
Run Code Online (Sandbox Code Playgroud)fruits[5] = 'mango'; console.log(fruits[5]); // 'mango' console.log(Object.keys(fruits)); // ['0', '1', '2', '5'] console.log(fruits.length); // 6增加长度.
Run Code Online (Sandbox Code Playgroud)fruits.length = 10; console.log(Object.keys(fruits)); // ['0', '1', '2', '5'] console.log(fruits.length); // 10但是,减小length属性会删除元素.
Run Code Online (Sandbox Code Playgroud)fruits.length = 2; console.log(Object.keys(fruits)); // ['0', '1'] console.log(fruits.length); // 2
Roh*_*har 14
JavaScript数组被视为对象(尽管它们是Array的实例).因此,当您编写时arr.lenght,它将视为lenght未定义的对象的属性.因此,您不会收到错误.
它只是试图获得一个未定义的属性.此外,在您的情况下,循环只是不执行,因为循环的条件永远不会满足.
标准JavaScript数组根本不是真正的数组,它们是对象,如果你读取了一个不存在的对象属性(比如lenght),你就得到了值undefined(即使在严格模式下):
console.log(({}).foo); // undefinedRun Code Online (Sandbox Code Playgroud)
当您undefined在与数字一起使用<或>与数字一起使用的关系操作中,它会转换为数字,但它获得的数字值是特殊数字NaN,它具有始终导致比较为假的奇怪属性:
console.log(NaN < 0); // false
console.log(NaN > 0); // false
console.log(NaN === 0); // false
console.log(NaN === NaN); // false!!Run Code Online (Sandbox Code Playgroud)
在简单的情况下,Linter工具通常会选择这些东西.
或者,TypeScript在JavaScript之上提供了一个完整的静态类型,可以捕获这些类型的错误.
如果你想(这很可能是矫枉过正),你可以换一个代理在你的对象,当你试图读取并不存在的属性,它扔了积极的错误:
function proactive(obj) {
return new Proxy(obj, {
get(target, propName, receiver) {
if (!Reflect.has(target, propName)) {
throw new TypeError(`Property '${propName}' not found on object`);
}
return Reflect.get(target, propName, receiver);
}
});
}
const a = proactive(["a", "b"]);
a.push("c");
for (let i = 0; i < a.length; ++i) {
console.log(a[i]);
}
console.log(`Length is: ${a.lenght}`); // Note the typoRun Code Online (Sandbox Code Playgroud)
.as-console-wrapper {
max-height: 100% !important;
}Run Code Online (Sandbox Code Playgroud)
但是,有一个重要的运行时惩罚.
¹ (这是我贫血的小博客上的帖子)
您可以轻松地向arr对象添加新属性,JavaScript不会向您发出警告,而是会尝试查找您正在调用的属性,如果它没有找到任何此类结果将是未定义的,那么比较实际上是i < undefined每次因为您正在调用尚未在对象上创建的属性.我建议你阅读JavaScript中的"use strict"做什么,背后的原因是什么?.
循环的上限被指定为lenght局部变量长度的拼写错误.在运行时,lenght将评估为undefined,所以检查0 < undefined是false.因此,循环体永远不会被执行.
| 归档时间: |
|
| 查看次数: |
6383 次 |
| 最近记录: |