面试官爱问的 Object.defineProperty,90%的人倒在这些细节上!

我们都知道Vue2中的响应式原理使用了Object.defineProperty, 那么你知道Object.defineProperty的一些使用细节吗!在面试过程中遇到这些细节考察,你是否可以轻松面对呢!今天我们就来探索一下Object.defineProperty使用的4个细节点。

一、 Object.defineProperty定义对象的默认行为

面试官:请说出下面代码的输出结果。

js 复制代码
function test1() {
  var a = {};
  var obj = Object.defineProperty(a, "b", {
    value: 1,
  });
  return obj;
}

var obj1 = test1();
console.log("结果1:", obj1);
obj1.b = 2;
console.log("结果2:", obj1);
obj1.c = 3;
for (var key in obj1) {
  console.log("结果3:", obj1[key]);
}
delete obj1.b;
console.log("结果4:", obj1);

答案如下:

对于结果1相信大家都觉得正常,不用思考就能写出答案,但是结果2、3、4,就需要你对Object.defineProperty的默认行为有所掌握了。结果2、3、4证明了Object.defineProperty 的3个默认行为:

  • Object.defineProperty 定义的属性默认不可以修改
  • Object.defineProperty 定义的属性默认不可枚举
  • Object.defineProperty 定义的属性默认不能删除

那么如何才能将Object.defineProperty 定义的属性变成可以修改,可以枚举和可以删除的呢?这时需要在定义时添加 writable,enumerable, configurable 3个配置。具体使用如下:

js 复制代码
function test1() {
  var a = {};
  var obj = Object.defineProperty(a, "b", {
    value: 1,
    writable: true, // 定义是否可写,也就是否可以修改
    enumerable: true, // 定义是否可以枚举
    configurable: true, // 定义是否可以删除
  });
  return obj;
}

var obj1 = test1();
console.log("结果1:", obj1);
obj1.b = 2;
console.log("结果2:", obj1);
obj1.c = 3;
for (var key in obj1) {
  console.log("结果3:", obj1[key]);
}
delete obj1.b;
console.log("结果4:", obj1);

输出结果如下:

二、Object.defineProperty 中getter setter方法的使用

面试官:请用Object.defineProperty 写一个简单的响应式

分析: 其实这主要就是考察你是否知道Object.defineProperty中的getter setter方法的用法, 实现方式如下:

js 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>响应简单实现</title>
  </head>
  <body>
    <div>
      <button id="btn">加一</button>
      <p>result:<span id="result">0</span></p>
    </div>
    <script>
      function reactive() {
        var obj = {};
        var result = 0;
        var obj2 = Object.defineProperty(obj, "result", {
          get: function (value) {
            return result;
          },
          set: function (newVal) {
            console.log(newVal);
            result++;
            document.getElementById("result").innerHTML = newVal;
          },
        });

        return obj;
      }
      var obj = reactive();
      document.getElementById("btn").onclick = function () {
        obj.result++;
      };
    </script>
  </body>
</html>

当点击按钮加一的时候,你会看到页面的result 更新来了,而在点击事件里面我们并没有去操作dom,这其实就是Vue2实现响应式的底层核心原理,只是Vue2中封装得更完善,可配置性更高。

三、Object.defineProperty 中, value 和getter setter 方法的互斥性

面试官: 请问下面代码会输出什么

js 复制代码
function test() {
  var obj = {};
  Object.defineProperty(obj, "b", {
    value: 1,
    get: function () {
      return 5;
    },
    set: function (newVal) {},
  });
  return obj;
}

var newObj = test();
console.log(newObj);

答案是什么也不会输出,会直接报错:

这里其实不只是get setter 和value 不能共存,getter setter 和writable, enumerable 也不能共存,只有getter setter 和getter setter 一起的时候不会报错

四、 Object.defineProperties

面试官: 请问Object.defineProperty 可以同时定义多个属性吗?可以的话怎么定义,不可以的话有其他解决方案吗?

答案是Object.defineProperty不可以同时定义多个属性,可以使用Object.defineProperties 来解决。具体使用方式如下:

js 复制代码
function test() {
  var obj = {};
  Object.defineProperties(obj, {
    a: {
      value: 1,
      writable: true,
      enumerable: true,
      configurable: true,
    },
    b: {
      value: 2,
    },
  });
  return obj;
}

var newObj = test();
console.log(newObj);

总结

本篇通过4个面试题来加深对Object.defineProperty 的理解,希望看了本篇遇到类似的面试题能够顺利通过,,感谢收看

相关推荐
顾北125 分钟前
AI对话应用接口开发全解析:同步接口+SSE流式+智能体+前端对接
前端·人工智能
iDao技术魔方18 分钟前
深入Vue 3响应式系统:为什么嵌套对象修改后界面不更新?
javascript·vue.js·ecmascript
历程里程碑22 分钟前
普通数组-----除了自身以外数组的乘积
大数据·javascript·python·算法·elasticsearch·搜索引擎·flask
摸鱼的春哥23 分钟前
春哥的Agent通关秘籍07:5分钟实现文件归类助手【实战】
前端·javascript·后端
念念不忘 必有回响26 分钟前
viepress:vue组件展示和源码功能
前端·javascript·vue.js
Amumu1213830 分钟前
Vue3 Composition API(一)
开发语言·javascript·ecmascript
C澒32 分钟前
多场景多角色前端架构方案:基于页面协议化与模块标准化的通用能力沉淀
前端·架构·系统架构·前端框架
崔庆才丨静觅33 分钟前
稳定好用的 ADSL 拨号代理,就这家了!
前端
江湖有缘35 分钟前
Docker部署music-tag-web音乐标签编辑器
前端·docker·编辑器
hzb6666636 分钟前
unictf2026
开发语言·javascript·安全·web安全·php