面试题答案
一键面试严格模式下 Object.defineProperty
中 getter
和 setter
隐式类型转换规则
- 严格性要求:严格模式下,
getter
和setter
函数在处理隐式类型转换时遵循更严格的规则。例如,getter
必须返回一个值,如果没有显式返回,将返回undefined
,而不会像非严格模式下尝试进行隐式类型转换。- 示例:
'use strict'; let obj = {}; Object.defineProperty(obj, 'prop', { get: function () { // 没有显式返回值,严格模式下返回 undefined }, set: function (value) { this._prop = value; } }); console.log(obj.prop); // 输出 undefined
setter
中的类型转换:setter
函数接收的值会遵循基本的 JavaScript 类型转换规则,但不会进行某些宽松的隐式转换。例如,当设置属性值为null
或undefined
时,不会自动转换为其他类型。- 示例:
'use strict'; let obj = {}; Object.defineProperty(obj, 'prop', { get: function () { return this._prop; }, set: function (value) { if (typeof value!=='string') { throw new TypeError('Value must be a string'); } this._prop = value; } }); try { obj.prop = null; } catch (e) { console.log(e.message); // 输出 'Value must be a string' }
与非严格模式下的区别
getter
返回值:在非严格模式下,如果getter
函数没有显式返回值,会尝试将函数内部的某些操作结果进行隐式类型转换作为返回值。例如,如果getter
函数最后执行了一个表达式,可能会将该表达式的结果返回,即使没有return
语句。而严格模式下,没有return
语句则返回undefined
。- 非严格模式示例:
let obj = {}; Object.defineProperty(obj, 'prop', { get: function () { 1 + 2; // 非严格模式下,该表达式结果可能被隐式返回 }, set: function (value) { this._prop = value; } }); console.log(obj.prop); // 输出 3(非严格模式特殊行为)
setter
类型宽松度:非严格模式下,setter
函数接收的值可能会进行更宽松的隐式类型转换。例如,即使setter
期望一个字符串类型,传入null
或undefined
时可能不会报错,而是进行一些隐式转换(虽然不一定符合预期)。而严格模式下,更倾向于抛出类型错误。
在复杂对象嵌套结构中的影响
- 数据读取:在复杂对象嵌套结构中,严格模式下的
getter
规则确保了每个层级的属性读取都遵循预期的类型返回规则。如果某个嵌套对象的getter
没有显式返回值,会明确返回undefined
,避免了非严格模式下可能出现的意外隐式返回值导致的数据读取错误。- 示例:
'use strict'; let nestedObj = {}; Object.defineProperty(nestedObj, 'inner', { value: {} }); Object.defineProperty(nestedObj.inner, 'prop', { get: function () { // 没有显式返回值 } }); console.log(nestedObj.inner.prop); // 输出 undefined
- 数据写入:
setter
的严格类型转换规则在复杂对象嵌套结构中有助于保持数据的一致性。当向嵌套属性赋值时,严格模式下的setter
会按照预期的类型转换规则处理值,如果不符合类型要求会抛出错误,防止错误的数据类型进入对象结构,而非严格模式下可能会允许一些不符合预期的类型转换,导致数据结构混乱。- 示例:
'use strict'; let nestedObj = {}; Object.defineProperty(nestedObj, 'inner', { value: {} }); Object.defineProperty(nestedObj.inner, 'prop', { get: function () { return this._prop; }, set: function (value) { if (typeof value!=='number') { throw new TypeError('Value must be a number'); } this._prop = value; } }); try { nestedObj.inner.prop = 'not a number'; } catch (e) { console.log(e.message); // 输出 'Value must be a number' }
综上所述,严格模式下 Object.defineProperty
的 getter
和 setter
隐式类型转换规则更加严格,有助于编写更健壮、可预测的代码,特别是在复杂对象嵌套结构中,能有效避免因隐式类型转换导致的错误。