tech share
  • tech-share
  • Engineering
    • 登录鉴权
    • SSR 页面路由
    • npm 版本号
    • 缓存
    • 数据库容灾
    • 动态效果导出 gif
    • Chrome-devtools
    • C 端 H5 性能优化
    • Docker
    • Monorepo 最佳实践
    • 技术架构演化
    • 项目规范最佳实践
    • snowpack
    • 静态资源重试
    • 前端页面渲染分析
    • Git
    • 前端重构
    • 微前端
    • 项目依赖分析
    • 前端监控原理
    • webpack
    • BS 架构与 CS 架构
    • HTTPS
    • package-lock.json 生成逻辑
    • SVN(Subversion)
    • 数据库分类
    • gulp
    • 前端架构
    • Bundle & Bundless
    • 控制反转 IoC
  • JavaScript
    • Javascript 性能
    • JavaScript 原型(2) - 原型与原型链
    • JavaScript 原型(1) - 构造函数
    • JavaScript - Promise
    • ES6 解构赋值
    • 前端离线化
    • Proxy
    • Object.defineProperty()简介
    • TypeScript
  • MachineLearning
    • GAN生成对抗网络
    • 虚拟对抗训练
    • 深度度量学习
    • 原型网络
    • PyTorch优化器
    • 隐马尔可夫模型2
    • Shapley Value 算法
    • Embarassingly Autoencoder算法
    • AutoRec算法及其后续发展
    • 深度学习常用激活函数
    • 序列预测ConvTran算法
    • 联邦学习
    • 深度学习推荐系统算法整理
    • 隐马尔可夫模型
    • 黎曼优化方法
    • FM算法
    • 机器学习常见评价指标
    • VAE算法
    • Adam优化器详解
    • Transformer算法
    • Self-attention 推荐算法
    • CNN 卷积神经网络
    • 图嵌入
    • 集成学习算法
    • RecBole开源框架
    • NCE-PLRec
    • 深度学习初始化方法
    • RNN循环神经网络
    • PyTorch数据处理
    • PyTorch安装和基本操作
    • XGBoost算法
    • NCF算法与简单MF的对比
    • 计算最佳传输
  • CSS
    • 什么是BFC
    • 纯CSS实现可拖动布局
    • 滚动穿透解决方案
  • React
    • React 生命周期
    • React Ref
    • React Hooks
    • SWR
    • React 数据流
    • React 函数式组件和类组件的区别
  • 可视化
    • OffscreenCanvas
    • Echarts 平滑曲线端点为什么不平滑
    • 颜色空间
    • 词云布局解析
    • 3D 数学基础
    • Canvas 图片处理
    • GLGL ES
    • WebGL 中绘制直线
    • Graphics API
    • 现代计算机图形学基础
    • Canvas 灰度
  • Vue
    • Vue2.x全局挂载整理
    • Vue2.6.x源码阅读
      • Vue2.6.x源码阅读 - 2.目录结构分析
      • Vue2.6.x源码阅读 - 4.源码阅读-platform
      • Vue2.6.x源码阅读 - 1.准备工作
      • Vue2.6.x源码阅读 - 5.源码阅读-core-Vue构造函数
      • Vue2.6.x源码阅读 - 7.源码阅读-core-响应式原理
      • Vue2.6.x源码阅读 - 3.源码阅读-shared
      • Vue2.6.x源码阅读 - 6.源码阅读-core-组件挂载
    • Vue + TypeScript Web应用实践
    • Vue2.x指令
    • nextTick()的使用
    • vue-cli2.x 的使用与项目结构分析
    • Vue响应式原理及总结
    • VueX的使用
    • Electron-Vue + Python 桌面应用实践
    • Vite
    • Vue组件通信整理
    • 记录一个问题的探索过程
  • Linux
    • memcg
  • GameDev
    • 游戏中的几种投影视图
    • 从零开始写软渲染器06
    • 从零开始写软渲染器05
    • 从零开始写软渲染器04
    • 从零开始写软渲染器03
    • 从零开始写软渲染器02
    • 从零开始写软渲染器01
    • 从零开始写软渲染器00
    • 现代游戏常用的几种寻路方案(一)
  • Node
    • NPM Dependency
    • Node 优势
    • Node Stream
    • Node 模块系统
  • HTML
    • html5语义与结构元素
  • 跨端
    • Flutter 介绍
  • Golang
    • Golang 基础
  • AR
    • SceneKit
由 GitBook 提供支持
在本页
  • 1. 定义
  • 2. 语法
  • 3. 属性描述符
  • 4. 属性描述符的键值
  • 数据描述符独有的两个键值(value, writable)
  • 存取描述符独有的两个键值(get, set)
  • 混合使用两种描述符的键值
  • 数据描述符和存取描述符共同具有的键值(configurable, enumerable)

这有帮助吗?

  1. JavaScript

Object.defineProperty()简介

Object.defineProperty() 是一个定义在 Object 构造函数上的方法。从命名就可以看出,此方法用于定义对象的属性。Vue 中就是使用此方法完成数据劫持,并实现双向绑定的。通过对此方法的学习,也为之后熟悉 Vue 双向绑定做准备。

1. 定义

  • 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

2. 语法

Object.defineProperty(obj, prop, descriptor);
  • obj : 要在其上定义属性的对象

  • prop : 要定义或修改的属性的名称

  • descriptor : 将被定义或修改的属性描述符

  • 返回值 : 被传递给函数的对象

3. 属性描述符

  • 对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。

  • 数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。

  • 存取描述符是由 getter-setter 函数对描述的属性。

  • 属性描述符只能同时为两个形式中的一个。

4. 属性描述符的键值

把属性本身想象为一个对象,键值参数其实就用于描述该对象的属性。键值共有六个,具有以下表格中的特性。

属性名

value

get

set

writable

enumerable

configurable

默认值

undefined

undefined

undefined

false

false

false

数据描述符

Yes

No

No

Yes

Yes

Yes

存取描述符

No

Yes

Yes

No

Yes

Yes

数据描述符独有的两个键值(value, writable)

  • value : 用于定义属性的值。

  • writable : 用于描述属性是否可写。

一个很简单的应用 :

let coder = {};
Object.defineProperty(coder, "lang", {
  value: "JavaScript",
  writable: true,
});
console.log(coder.lang); // "JavaScript"

// writable为true时,对象的属性可写
coder.lang = "Java";
console.log(coder.lang); // "Java"

当然,当我们不添加 writable 属性时,属性的值将不可修改(默认为 false)

let coder = {};
Object.defineProperty(coder, "lang", {
  value: "JavaScript",
});
console.log(coder.lang); // "JavaScript"

// writable为默认值时,对象的属性不可写
coder.lang = "Java";
console.log(coder.lang); // "JavaScript"

存取描述符独有的两个键值(get, set)

  • get : 一个给属性提供获取值的方法,该方法返回值被用作属性值。无默认值则返回 undefined。

  • set : 一个给属性提供设置值的方法。该方法将接受唯一参数,并将该参数的新值分配给该属性。

let coder = {};
let tmp = "JavaScript";
Object.defineProperty(coder, "lang", {
  value: "JavaScript",
  writable: true,
  get: () => {
    return tmp;
  },
  set: (val) => {
    tmp = val;
  },
});
// 直接获取对象属性值
console.log(coder.lang); // "JavaScript"

// 设置对象属性值后再次获取
coder.lang = "Java";
console.log(coder.lang); // "Java"

混合使用两种描述符的键值

当上述两类特有的键值被一起使用时,就违反了描述符本身的定义,出现语法错误。

数据描述符和存取描述符共同具有的键值(configurable, enumerable)

  • configrable : 描述属性是否配置,以及可否删除。

  • enumerable : 描述属性是否会出现在 for in 或者 Object.keys()的遍历中。

先对configurable进行分析

let coder = {};
Object.defineProperty(coder, "lang", {
  value: "JavaScript",
  writable: true,
  configurable: false,
  enumerable: true,
});
// 首先,configurable为false时,属性不可删除
delete coder.lang;
console.log(coder.lang); // "JavaScript"

// 但如果writable为true可以通过赋值修改内容
coder.lang = "Java";
console.log(coder.lang); // "Java"

// 通过配置方法直接改值则会报错
Object.defineProperty(coder, "lang", {
  value: "JavaScript",
});
// Uncaught TypeError: Cannot redefine property: lang

有个神奇的特殊情况是,configurable 为 false 时,writable 的值可以从 true 改为 false,反之则不行。

再分析enumerable,可以发现与其定义完全符合。

let coder = {};
coder.lang = "JavaScript";
Object.defineProperty(coder, "frame", {
  value: "Vue",
  enumerable: false,
});
Object.defineProperty(coder, "work", {
  value: "996",
  enumerable: true,
});

// 通过for in与Object.keys()方法遍历对象
for (let key in coder) {
  console.log(key);
}
// "lang"  "work"
console.log(Object.keys(coder)); // ["lang", "work"]

在以上的使用中,我们又可以发现一个特殊的用法,即直接给对象属性赋值。

  • 当调用 Object.defineProperty()配置属性时,没有赋值的数据描述符取默认值。

  • 当直接对属性赋值时,如以上代码块第二行,则value以外的数据描述符均为 true。

上一页Proxy下一页TypeScript

最后更新于4年前

这有帮助吗?

数据描述符与存取描述符共存