类型错误:无法在 JavaScript 中设置未定义的属性

TypeError: 无法在 JavaScript 中设置 Undefined 的属性

TypeError: Cannot set properties of Undefined in JavaScript

在值上设置属性时发生“类型错误:无法设置未定义的属性” undefined

要解决该错误,请确保该值是预期类型(对象或数组),然后再为其设置属性。

无法设置未定义的属性

以下是对象如何发生错误的示例。

索引.js
const example = undefined; // ⛔️ TypeError: Cannot set properties of undefined (setting 'myKey') example.myKey = 'my value';

undefined我们试图在导致错误的值上设置属性。

这是数组如何发生错误的示例。

索引.js
const example = undefined; // ⛔️ TypeError: Cannot set properties of undefined (setting '0') example[0] = 'my value';

我们试图0根据undefined导致错误的值更新索引处的数组元素。

为变量何时提供回退值undefined

要解决该错误,请在变量为 的情况下提供回退值
undefined

下面是一个在变量为 时提供空对象回退值的示例undefined

索引.js
const fromDb = undefined; const obj = fromDb || {}; obj.myKey = 'my value'; console.log(obj); // 👉️ {myKey: 'my value'}

如果左侧的值是假的(例如undefined),我们使用逻辑 OR (||) 运算符提供回退值。

如果左边的值为 falsy,则逻辑 OR (||) 运算符返回右边的值。

下面是我们如何使用逻辑 OR (||) 运算符在变量为undefined.

索引.js
const fromDb = undefined; const arr = fromDb || []; arr[0] = 'my value'; console.log(arr); // 👉️ ['my value']

您还可以使用无效合并 (??) 运算符来获得相同的结果。

索引.js
const fromDb = undefined; const obj = fromDb ?? {}; // 👈️ nullish coalescing obj.myKey = 'my value'; console.log(obj); // 👉️ {myKey: 'my value'}

如果空合并运算符 (??)左侧的值
等于
nullor undefined,则返回右侧的值,否则返回运算符左侧的值。

如果fromDb变量存储一个undefined或一个null值,则返回一个空对象。

undefined在设置属性之前检查变量是否存在

您还可以在设置属性之前使用一个简单的if语句来检查变量是否存在
undefined

索引.js
const obj = undefined; if (obj != undefined) { obj.property = 'value'; } console.log(obj); // 👉️ undefined

if块仅在变量不存储值时运行undefined

为对象或数组中未定义的值设置嵌套属性

undefined尝试在对象或数组中的值上设置嵌套属性时最常发生错误

索引.js
const obj = {}; // ⛔️ Cannot set properties of undefined (setting 'b') obj['a']['b'] = 'my value'; const arr = []; // ⛔️ Cannot set properties of undefined (setting '0') arr[0][0] = 'my value';

尝试访问obj['a']返回undefined,因为a对象中不存在该键。

同样,在索引处访问数组0会返回一个undefined值,因为数组中该索引处没有元素。

当我们尝试在一个值上设置属性或索引时undefined,会发生错误。

要解决该错误,请确保您尝试为其设置属性的对象或数组存在。

这是为对象执行此操作的示例。

索引.js
const obj = {}; if (obj['a']) { obj['a']['b'] = 'my value'; } else { obj['a'] = { b: 'my value', }; } console.log(obj); // 👉️ {a: {b: 'my value'}}

如果访问a对象的属性返回一个undefined值,我们将该a属性设置为包含该属性的对象b

如果a属性是在对象上定义的,我们将b属性设置为等于my value

这是相同的示例,但适用于二维数组。

索引.js
const arr = []; if (Array.isArray(arr[0])) { arr[0][0] = 'my value'; } else { arr[0] = ['my value']; } console.log(arr); // 👉️ [ ['my value'] ]

我们首先检查索引处的数组元素是否0为数组。如果满足条件,我们将其在索引处的值设置0my value

如果索引处的数组元素0不是数组,我们将其设置为包含该值的数组。

确保在调用函数时指定所需的参数

如果您应该将对象或数组作为参数传递给函数,但没有提供,也可能会发生该错误。

索引.js
function example(obj) { obj.first = 'John'; obj.last = 'Smith'; return obj; } // ⛔️ Cannot set properties of undefined (setting 'first') example();
该函数需要一个对象参数,但是我们没有提供一个,因此函数中的值objundefined错误的。

您可以为该obj参数设置一个默认值来解决该问题。

索引.js
// 👇️ Provide an empty object as a default value function example(obj = {}) { obj.first = 'John'; obj.last = 'Smith'; return obj; } const result = example(); console.log(result); // 👉️ {first: 'John', last: 'Smith'}

我们将一个空对象设置为obj参数的默认值。

如果调用函数时未传递参数,则变量obj默认为空对象。

确保您没有
忘记使用该return语句
,因为不返回值的函数 return
undefined

确保将 JS 脚本标签放在 body 标签的底部

body在浏览器环境中工作时,请确保在声明 DOM 元素后将JS 脚本标记放在标记的底部。

索引.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <div class="box">Box 1</div> <div class="box">Box 2</div> <div class="box">Box 3</div> <!-- ✅ GOOD - div already exists ✅ --> <script src="index.js"></script> </body> </html>

现在您将能够访问index.js文件中的 DOM 元素。

索引.js
const boxes = document.getElementsByClassName('box'); // HTMLCollection(3) [div.box, div.box, div.box] console.log(boxes); console.log(boxes[0]); // 👉️ div.box boxes[0].style.color = 'red';

HTML 代码是从上到下解析的,因此如果您将 JS 脚本标记放在它尝试访问的 DOM 元素上方,它们将不会在您的index.js
文件中可用。

如果您需要迭代一个集合并为每个元素设置一个属性,请使用该Array.forEach()方法。

索引.js
// 👇️ convert to Array const boxes = Array.from(document.getElementsByClassName('box')); // 👇️ iterate over array boxes.forEach(element => { element.style.color = 'red'; });

我们使用该Array.from()方法将 HTML 集合转换为数组,并使用该Array.forEach()方法遍历数组并为每个元素设置属性。

您还可以使用for...of循环遍历集合并为每个元素设置一个属性。

索引.js
const boxes = document.getElementsByClassName('box'); for (const element of boxes) { element.style.color = 'red'; }

for …of语句用于循环遍历可迭代对象,如数组、字符串MapSet
NodeList对象generators

下面是解决浏览器环境中特定属性错误的示例。

不能设置未定义的属性(设置’display’)

“TypeError:无法设置未定义的属性(设置‘显示’)”错误发生在试图设置属性display值时undefined

要解决该错误,请确保在访问有效 DOM 元素上的属性display后访问该属性。style

下面是错误如何发生的示例。

索引.js
const elements = []; // ⛔️ Uncaught TypeError: Cannot set properties of undefined (setting 'display') elements[0].display = 'block';

无法设置未定义的属性显示

这是一个工作示例的 HTML 代码。

索引.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <div class="container">Content 1</div> <div class="container">Content 2</div> <div class="container">Content 3</div> <!-- ✅ GOOD - div already exists ✅ --> <script src="index.js"></script> </body> </html>
请注意,我们将脚本放在创建元素的代码下方如果我们将脚本放在 DOM 元素之上,我们将无法在文件中访问它们 divindex.js

这是相关的 JavaScript 代码。

索引.js
const elements = document.getElementsByClassName('container'); console.log(elements); // 👉️ [div.container, div.container, div.container] // ✅ Update display property of first element elements[0].style.display = 'block'; // ✅ Update display property for all elements in the NodeList for (const element of elements) { element.style.display = 'block'; }

我们使用该getElementsByClassName方法获取一个类数组对象,其中包含类为container.

第一个示例显示如何更新display节点列表中第一个元素的属性。我们访问位置处的元素0并直接更新属性。

如果您需要display为具有特定类的所有元素设置属性,请使用循环for...of来迭代类似数组的对象。

索引.js
const elements = document.getElementsByClassName('container'); console.log(elements); // 👉️ [div.container, div.container, div.container] // ✅ Update display property for all elements in the NodeList for (const element of elements) { element.style.display = 'block'; }

在每次迭代中,我们将display元素的属性设置为block

额外资源

您可以通过查看以下教程来了解有关相关主题的更多信息: