JavaScript之Object.defineProperty()

这篇具有很好参考价值的文章主要介绍了JavaScript之Object.defineProperty()。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 对象的定义与赋值

经常使用的定义与赋值方法obj.prop =value或者obj['prop']=value

let Person = {};
Person.name = "Jack";
Person["gender"] = "female";
console.log(Person.name); // Jack
console.log(Person.gender); // female
console.log(Person); // {name: 'Jack', gender: 'female'}

2. Object.defineProperty()语法说明

Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性

Object.defineProperty(obj, prop, desc)
  1. obj 需要定义属性的当前对象
  2. prop 当前需要定义的属性名
  3. desc 属性描述符

一般通过为对象的属性赋值的情况下,对象的属性可以修改也可以删除,但是通过Object.defineProperty()定义属性,通过描述符的设置可以进行更精准的控制对象属性。

3. 属性的特性以及内部属性

javacript 有三种类型的属性

  1. 命名数据属性:拥有一个确定的值的属性。这也是最常见的属性
  2. 命名访问器属性:通过gettersetter进行读取和赋值的属性
  3. 内部属性:由JavaScript引擎内部使用的属性,不能通过JavaScript代码直接访问到,不过可以通过一些方法间接的读取和设置。比如,每个对象都有一个内部属性[[Prototype]],你不能直接访问这个属性,但可以通过Object.getPrototypeOf()方法间接的读取到它的值。虽然内部属性通常用一个双吕括号包围的名称来表示,但实际上这并不是它们的名字,它们是一种抽象操作,是不可见的,根本没有上面两种属性有的那种字符串类型的属性

4. 属性描述符

通过Object.defineProperty()为对象定义属性,有两种形式,且不能混合使用,分别为数据描述符,存取描述符,下面分别描述下两者的区别:

1. 数据描述符 --特有的两个属性(value,writable)

注意:当使用了writable和value属性,不允许使用getter或setter这两个方法

  • writable: 描述对象是否可写(是否只读)
    • 当我们之间在一个对象上定义某个属性时, writable默认为true
    • 当我们通过属性描述符定义一个属性时, writable默认为false
let Person = {}
Object.defineProperty(Person, 'name', {
   value: 'jack',
   writable: true // 是否可以改变
})
let Person = {};
Object.defineProperty(Person, "name", {
    value: "Jack",
    // writable默认值是false, 不能改变属性的值
});
Person.name = "rose";
console.log(Person.name); // Jack
-------------------------------------------------------------------------------------------
let Person = {};
Object.defineProperty(Person, "name", {
    value: "Jack",
    writable: true, // 可以改变value值
});
Person.name = "rose";
console.log(Person.name); // rose

注意,如果描述符中的某些属性被省略,会使用以下默认规则:

属性名 默认值
value undefined
get undefined
set undefined
writable false
enumerable false
configurable false

2. 存取描述符 --是由一对 getter、setter 函数功能来描述的属性

注意:当使用了getter或setter方法,不允许使用writable和value这两个属性

get:一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回值被用作属性值。默认为undefined

set:一个给属性提供setter的方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认值为undefined

let Person = {}
let temp = null
Object.defineProperty(Person, 'name', {
  get: function () {
    return temp
  },
  set: function (val) {
    temp = val
  }
})
let Person = {};
let temp = null;
Object.defineProperty(Person, "name", {
    get: function () {
        return temp;
    },
    set: function (val) {
        temp = val;
    },
});

Person.name = "Jack";
console.log(Person.name, temp); // Jack Jack

temp = "rose";
console.log(Person.name, temp); // rose rose

3. 存取器描述

当使用存取器描述属性的特性的时候,允许设置以下特性属性:

var obj = {};
Object.defineProperty(obj, "newKey", {
    get: function () {} | undefined,
    set: function (value) {} | undefined,
    configurable: true | false,
    enumerable: true | false,
});

getter/setter:

当设置或获取对象的某个属性的值的时候,可以提供getter/setter方法。

  • getter 是一种获得属性值的方法
  • setter是一种设置属性值的方法。

在特性中使用get/set属性来定义对应的方法。

var obj = {};
var initValue = "hello";
Object.defineProperty(obj, "key", {
    get: function () {
        //当获取值的时候触发的函数
        return initValue;
    },
    set: function (value) {
        //当设置值的时候触发的函数,设置的新值通过参数value拿到
        initValue = value;
    },
});
//获取值
console.log(obj.key); //hello

//设置值
obj.key = "change value";

console.log(obj.key); //change value

注意:get或set不是必须成对出现,任写其一就可以。如果不设置方法,则get和set的默认值为undefined

4. 数据描述符和存取描述均具有以下描述符

  • configrable 描述属性是否配置,以及可否可以通过delete删除(是否可配置)
    • 当我们之间在一个对象上定义某个属性时, configrable默认为true
    • 当我们通过属性描述符定义一个属性时, configrable默认为false
  • enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中(是否枚举)
    • 当我们之间在一个对象上定义某个属性时, enumerable默认为true
    • 当我们通过属性描述符定义一个属性时, enumerable默认为false

1. configrable 代码片段分析

configurable:false不能删除属性:

let Person = {};
Object.defineProperty(Person, "name", {
    value: "Jack",
    configurable: false,
});

console.log(delete Person.name); // Cannot delete property 'name' of #<Object>

configurable:false不能重新定义属性:

let Person = {};
Object.defineProperty(Person, "name", {
    value: "Jack",
    configurable: false,
});

Object.defineProperty(Person, "name", {
    value: "rose", // Cannot redefine property: name
});

在configurable:false但writable为true`的情况下可以修改属性值:

let Person = {};
Object.defineProperty(Person, "name", {
    value: "Jack",
    configurable: false,
    writable: true,
});

// 通过属性定义的形式可以修改name的值
Object.defineProperty(Person, "name", {
    value: "rose",
});

console.log(Person.name); // rose

// 通过赋值的形式可以修改name的值
Person.name = 'zgc'
console.log(Person.name);

configurable:true但writable为false的情况下可以通过属性定义的形式可以修改name的值:

let Person = {};
Object.defineProperty(Person, "name", {
    value: "Jack",
    configurable: true,
    writable: false,
});

// 通过属性定义的形式可以修改name的值
Object.defineProperty(Person, "name", {
    value: "rose",
});

console.log(Person.name); // rose

// 通过赋值的形式不可以修改, 因为writable为flse
Person.name = "zgc";
console.log(Person.name);

2. enumerable 代码片段分析

let Person = {};
Object.defineProperty(Person, "name", {
    value: "Jack",
    configurable: false,
    writable: false, // 默认值
});

Person.gender = "male";

Object.defineProperty(Person, "age", {
    value: 24,
    enumerable: true,
});

console.log(Object.keys(Person)); // ['gender', 'age']
for (let k in Person) {
    console.log(k); // gender, age
}

注意:以下二种区别文章来源地址https://www.toymoban.com/news/detail-487556.html

let Person = {};
Person.gender = "male";
// 等价于
Object.defineProperty(Person, "gender", {
    value: "male",
    configurable: true,
    enumerable: true,
    writable: true,
});

Object.defineProperty(Person, "age", {
    value: 24,
});
// 等价于
Object.defineProperty(Person, "age", {
    value: 24,
    configurable: false,
    enumerable: false,
    writable: false,
});

到了这里,关于JavaScript之Object.defineProperty()的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3的响应式赋值中数组array,对象object,集合set的重新赋值怎么操作,问过Chatgpt的答案

    vue3和ts结合开发的时候,总是会遇到引用数据类型的重新赋值的情况,但是在vue3中,又不能使用直接赋值的情况,因为会改变proxy的结构,导致响应式失败,那么该如何重新赋值响应式对象数据成为了一个技巧问题,今天它来了 如果是数组的话,踩坑点:**清空数组,然后再

    2024年02月15日
    浏览(46)
  • 详解vue中的Object.defineProperty

       如果想要age遍历的话 就设置属性 打印出来 发现有可以枚举的属性age  参考课程: 011_尚硅谷Vue技术_Object.defineProperty_哔哩哔哩_bilibili   // 1.Vue中的数据代理:     //    通过Vm对象来代理data对象中属性的操作(读/写)     // 2.Vue中数据代理的好处:     //   更加方便的

    2024年02月04日
    浏览(32)
  • Vue中的Object.defineProperty详解

    Vue中的Object.defineProperty是一个比较重要的方法,它是可以定义对象中属性的一个方法,相比于在对象中直接定义的对象,它更具有灵活性。 直接定义对象中的属性是这样的: 而Object.defineProperty可以直接在上面的对象中添加属性,如下面所示: 如果用上面的方法进行定义属性

    2024年02月13日
    浏览(30)
  • 使用object.defineProperty来更新数据示例

    vue+element UI 第001个 查看专栏目录: 按照VUE知识点 ------ 按照element UI知识点 echarts,openlayers,cesium,leaflet,mapbox,d3,canvas 免费交流社区 专栏目标 在vue和element UI联合技术栈的操控下,本专栏提供行之有效的源代码示例和信息点介绍,做到灵活运用。 (1)提供vue2的一些基本操

    2024年02月06日
    浏览(22)
  • 在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改

    一、Object.freeze()方法来冻结对象,防止对象被修改 Object.freeze() 是JavaScript中的一个方法,用于冻结一个对象。被冻结的对象不能再被修改。具体来说,它做了两件事情: 防止添加新的属性:尝试添加新属性将失败,不会抛出错误,但新属性不会被添加到对象中。 防止删除属

    2024年02月02日
    浏览(31)
  • JavaScript 数组Array存储方式及对象Object

    一、数组的存储 1、当声明一个变量时,var a = 111; 在后台计算机翻译时,var声明 a变量 所以此时会产生一个栈内存,变量 a 的初始值为undefined,然后 = 111 ; undefined消失,111的值被赋值给了a。如果多个变量赋值的话,栈内存的执行顺序是先进后出的顺序。也叫做压栈。栈内存

    2024年02月08日
    浏览(34)
  • ts定义对象类型Record<string, any>;和object、Object的区别

    Record 是 TS 内置的一个高级类型,是通过映射类型的语法来生成索引类型的 比如传入 \\\'a\\\' | \\\'b\\\' 作为 key,1 作为 value,就可以生成这样索引类型: 所以这里的 Recordstring, any 也就是 key 为 string 类型,value 为任意类型的索引类型,可以代替 object 来用,更加语义化一点: Record 与

    2024年02月16日
    浏览(28)
  • JavaScript中对象的定义、引用和复制

    JavaScript是一种广泛使用的脚本语言,其设计理念是面向对象的范式。在JavaScript中,对象就是一系列属性的集合,每个属性包含一个名称和一个值。属性的值可以是基本数据类型、对象类型或函数类型,这些类型的值相互之间有着不同的特点。本文将探讨JavaScript中对象的定义

    2024年02月02日
    浏览(25)
  • 【浅尝C++】继承机制=>虚基表/菱形虚继承/继承的概念、定义/基类与派生类对象赋值转换/派生类的默认成员函数等详解

    🏠专栏介绍:浅尝C++专栏是用于记录C++语法基础、STL及内存剖析等。 🎯每日格言:每日努力一点点,技术变化看得见。 我们生活中也有继承的例子,例如:小明继承了孙老师傅做拉面的手艺。继承就是一种延续、复用的方式。C++为了提高代码的可复用性,引入了继承机制,

    2024年04月10日
    浏览(38)
  • 【JavaScript】JavaScript 运算符 ⑤ ( 赋值运算符 | 基础赋值运算符 与 复合赋值运算符 )

    JavaScript 赋值运算符种类 : 基础赋值运算符 : 等于 : = ; 复合赋值运算符 : 加等 : += 减等 : -= 乘等 : *= 除等 : /= 取模等 : %= 有符号左移等 : = 有符号右移等 : = 无符号左移等 : = 无符号右移等 : = 在 JavaScript 语言中 , \\\" 赋值运算符 \\\" 的 作用是 为 变量 分配值 ; 最基础的 \\\" 赋值运算

    2024年03月25日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包