资讯专栏INFORMATION COLUMN

从Vue源码学习JavaScript之Object.defineproperty

BingqiChen / 2808人阅读

摘要:可以是任何有效的值数值,对象,函数等。当且仅当该属性的为时,才能被赋值运算符改变。存取描述符其余属性一个给属性提供的方法,如果没有则为。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。

Vue里面有个耳熟能详的词是Object.defineproperty,这篇文章就介绍一下这个属性。

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

Object.defineProperty(obj, prop, descriptor)

参数

obj:要在其上定义属性的对象

prop:要定义或者要修改的属性

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

descriptor属性描述符
属性描述符又可分为数据描述符和存取描述符,可以用getOwnPropertyDescriptors或者getOwnPropertyDescriptor获取到属性描述

数据描述符和存取描述符共有的属性包括:

configurable

当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除,如果为false,则不能删除或修改writable, configurable, enumerable。默认为 true。

var animal = {
    name: "cat"
}
console.log(Object.getOwnPropertyDescriptors(animal)) 
//name: {value: "cat", writable: true, enumerable: true, configurable: true}
console.log(animal.name) //cat
delete animal.name
console.log(animal.name) //undefined

Object.defineProperty(animal, "name", {
    value: "dog",
    configurable: false
})
console.log(Object.getOwnPropertyDescriptors(animal))
//name: {value: "dog", writable: false, enumerable: false, configurable: false}
console.log(animal.name) //dog
delete animal.name
console.log(animal.name) //dog

可以看到,configurable默认属性是true,设置为false之后,delete对象的属性将失效

需要注意的是,如果不是通过defineproperty定义的属性,描述符默认值都是true;通过defineproperty定义的属性,描述符默认是false

enumerable

当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中(for...in, Object.keys())。默认为 true。

let animal = {
    name: "cat"
 }
for (let i in animal) {
    console.log(animal[i]) //cat
}
Object.defineProperty(animal, "name", {
    enumerable: false
})
for (let i in animal) {
    console.log(animal[i]) //无输出
}

数据描述符其余属性:

value

该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。

writable

当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 true。

存取描述符其余属性:

get

一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。

let animal = {}
let name = "cat"
Object.defineProperty(animal, "name", {
  value: "cat",
  get: function () {
    return name
  }
})
//报错:Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #

let animal = {}
let name = "cat"
Object.defineProperty(animal, "name", {
    get: function () {
      return name
    }
})
console.log(animal.name) //cat



如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(value或writable)和(get或set)关键字,将会产生一个异常。

set

一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。

let animal = {}
let name = "cat"
Object.defineProperty(animal, "name", {
    get: function () {
      return name
    },
    set: function (val) {
      name = val
    }
})

如果访问者的属性是被继承的,它的 get 和set 方法会在子对象的属性被访问或者修改时被调用。如果这些方法用一个变量存值,该值会被所有对象共享。

可以借助中间值来解决

    let animal = {}
    let name = "cat"
    Object.defineProperty(animal, "name", {
        get: function () {
          return this.stored_x
        },
        set: function (val) {
          this.stored_x = val
        }
    })

    

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104015.html

相关文章

  • JavaScript 进阶深入理解数据双向绑定

    摘要:当我们的视图和数据任何一方发生变化的时候,我们希望能够通知对方也更新,这就是所谓的数据双向绑定。返回值返回传入函数的对象,即第一个参数该方法重点是描述,对象里目前存在的属性描述符有两种主要形式数据描述符和存取描述符。 前言 谈起当前前端最热门的 js 框架,必少不了 Vue、React、Angular,对于大多数人来说,我们更多的是在使用框架,对于框架解决痛点背后使用的基本原理往往关注...

    sarva 评论0 收藏0
  • vue框架的基本原理,简单实现一个todo-list

    摘要:前言最近在学习框架的基本原理,看了一些技术博客以及一些对源码的简单实现,对数据代理数据劫持模板解析变异数组方法双向绑定有了更深的理解。 前言 最近在学习vue框架的基本原理,看了一些技术博客以及一些对vue源码的简单实现,对数据代理、数据劫持、模板解析、变异数组方法、双向绑定有了更深的理解。于是乎,尝试着去实践自己学到的知识,用vue的一些基本原理实现一个简单的todo-list,完成...

    Karrdy 评论0 收藏0
  • Vue原理】依赖收集 - 源码基本数据类型

    摘要:当东西发售时,就会打你的电话通知你,让你来领取完成更新。其中涉及的几个步骤,按上面的例子来转化一下你买东西,就是你要使用数据你把电话给老板,电话就是你的,用于通知老板记下电话在电话本,就是把保存在中。剩下的步骤属于依赖更新 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【...

    VincentFF 评论0 收藏0
  • 源码解析 —— Vue的响应式数据流

    摘要:下面我们会向大家解释清楚为什么这个这么重要,以及它和的响应式数据流有什么关系。源码前面铺垫这么多就是希望大家能理解接下来要讲的响应式数据流。总结讲到这里大家应该都能够明白的响应式数据流是如何实现的。 Vue、React介绍 目前前端社区比较推崇的框架有Vue 和 React,公司内部许多端都自发的将原有的老技术方案(widget + jQuery)迁移到 Vue / React上了。我...

    LuDongWei 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<