面试官爱问的 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 的理解,希望看了本篇遇到类似的面试题能够顺利通过,,感谢收看

相关推荐
庞囧3 小时前
从输入 URL 到开始解析 HTML 之间:浏览器背后发生了什么
前端
少年阿闯~~3 小时前
解决HTML塌陷的方法
前端·html
徐小夕3 小时前
花了4个月时间,我写了一款支持AI的协同Word文档编辑器
前端·vue.js·后端
岁月向前4 小时前
小组件获取主App数据的几种方案
前端
用户47949283569154 小时前
TypeScript 和 JavaScript 的 'use strict' 有啥不同
前端·javascript·typescript
恒创科技HK5 小时前
香港服务器速度快慢受何影响?
运维·服务器·前端
bubiyoushang8885 小时前
MATLAB实现直流电法和大地电磁法的一维正演计算
前端·javascript·matlab
Mintopia5 小时前
🧠 AIGC模型的增量训练技术:Web应用如何低成本迭代能力?
前端·javascript·aigc
Mintopia5 小时前
🧩 Next.js在国内环境的登录机制设计:科学、务实、又带点“国风味”的安全艺术
前端·javascript·全栈