注意,一般来说,不可扩展对象的属性可能仍然可被删除。尝试将新属性添加到不可扩展对象将静默失败或抛出TypeError(最常见的情况是strict mode (en-US)中,但不排除其他情况)。...属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。...尝试删除一个密封对象的属性或者将某个密封对象的属性从数据属性转换成访问器属性,结果会静默失败或抛出TypeError(在严格模式 中最常见的,但不唯一)。 不会影响从原型链上继承的属性。...数据属性的值不可更改,访问器属性(有getter和setter)也同样(但由于是函数调用,给人的错觉是还是可以修改这个属性)。...(); // 试图通过 Object.defineProperty 更改属性 // 下面两个语句都会抛出 TypeError.
在configurable为true的情况下可多次调用Object.defineProperty( )修改同一属性。 在非严格情况下修改无法配置的属性操作会被忽略,在严格模式下会抛出错误。...这是使用访问器属性的常见方式,即设置一个属性的值会导致其他属性发生变化。 不一定非要同时指定 getter 和 setter。只指定 getter 意味着属性是不能写,尝试写入属性会被忽略。...在严格模式下,尝试写入只指定了 getter 函数的属性会抛出错误。类似地,只指定 setter 函数的属性也不能读,否则在非严格模式下返回 undefined,严格模式下报错。...),变量的可配置性为 true。..., // writable: true, // enumerable: true, // configurable: true // } [[Configurable]] 特性还有个作用,一旦把属性定义为不可配置的
分析一下,这个需求其实就是需要创建一个固定属性的对象,其属性不可增删,但属性值可更改。...属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。...尝试删除一个密封对象的属性或者将某个密封对象的属性从数据属性转换成访问器属性,结果会静默失败或抛出 TypeError(在严格模式 中最常见的,但不唯一)。...(绝对存在) 设置configurable为false,禁止配置(绝对存在) 禁止更改访问器属性(getter和setter) 语法 Object.seal(obj) 参数 参数 obj 代表将要被密封的对象...实际作用就是字面意思:冻结一个对象,使其属性和属性值都不可更改。用来实现这个需求显然是不合适的。
严格模式是一项 ES5 功能,它使 JavaScript 以更好的方式运行,因为启用严格模式会更改 JavaScript 语言的语义。...在 JavaScript 中,可以使用下面代码定义对象属性不可写 JavaScript 代码: const car = {}Object.defineProperty(car, 'color', { value...: Cannot set property color of # which has only a getter })() 非严格模式允许扩展一个不可扩展的对象: JavaScript 代码: const...: Cannot add property owner, object is not extensible })() 另外,非严格模式允许设置原始值的属性,而不会失败,但也没有做任何事情: JavaScript...string 'test'})() 删除错误 在非严格模式,如果你尝试删除无法删除的属性,JavaScript 只返回 false ,而在严格模式下,它会引发 TypeError: JavaScript
这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改(immutable)的。...存取描述符还具有以下可选键值: get属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。...data descriptors, get appears only in accessor descriptors 修改属性 如果属性已经存在,Object.defineProperty()将尝试根据描述符中的值以及对象当前的配置来修改这个属性...如果旧描述符将其configurable 属性设置为false,则该属性被认为是“不可配置的”,并且没有属性可以被改变(除了单向改变 writable 为 false)。...当属性不可配置时,不能在数据和访问器属性类型之间切换。 当试图改变不可配置属性(除了 value 和 writable 属性之外)的值时,会抛出TypeError,除非当前值和新值相同。
存取描述符同时具有以下可选键值: get:一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。...()将尝试根据描述符中的值以及对象当前的配置来修改这个属性。...如果旧描述符将其 configurable 属性设置为false,则该属性被认为是“不可配置的”,并且没有属性可以被改变(除了单向改变 writable 为 false)。...当属性不可配置时,不能在数据和访问器属性类型之间切换。 当试图改变不可配置属性(除了value和writable 属性之外)的值时会抛出TypeError,除非当前值和新值相同。...然而,如果一个不可写的属性被继承,它仍然可以防止修改对象的属性。
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。...Object.preventExtensions()将对象标记为不再可扩展,因此它将永远不会具有超出它被标记为不可扩展的属性。注意,一般来说,不可扩展对象的属性可能仍然可被删除。 ? ?...所以,密封之后不仅不能添加新属性,也不能重新配置或者删除任何现有属性(虽然可以修改属性的值)。...(); // 试图通过 Object.defineProperty 更改属性 // 下面两个语句都会抛出 TypeError....__proto__ 属性是一个访问器属性(一个getter函数和一个setter函数), 暴露了通过它访问的对象的内部[[Prototype]]。
attributes无关,它的副本始终是可写和可配置的 data 属性,例如: 1const original = Object.defineProperties({}, { 2prop: { 3...和 setter 都不会被如实地被复制:value 属性(用于数据属性),get 属性(用于 getter)和set 属性(用于 setter)是互斥的。...而其他所有内容:不复制原型,仅部分复制特殊对象,忽略不可枚举的属性,忽略大多数属性。 通常完全完全实现复制是不可能的:并非所有数据的都是一棵树,有时你并不需要所有属性,等等。...方法: Object.preventExtensions(obj) Sealing 可以防止扩展,并使所有属性都无法配置(大约:您无法再更改属性的工作方式)。...方法: Object.seal(obj) Freezing 使对象的所有属性不可写后将其密封。也就是说,对象是不可扩展的,所有属性都是只读的,无法更改它。
默认为false 设置为true可以被删除或可以重新设置特性; 设置为false,不能被可以被删除或不可以重新设置特性,只能将writable从true置为false 一旦把属性定义为不可配置的,就不能再把它便会可配置的...true, enumerable: true, configurable: true }); console.log( obj.newKey ); //报错:Uncaught TypeError...Object.defineProperty(obj, "newKey", { value: "hello", writable: false }); // 更改newKey的值...obj.key的值上下文" console.log(obj.key); // undefined 不一定非要同时指定getter和setter。...只指定getter意味着属性是不能写,尝试写入属性会被忽略。在严格模式下,尝试写入只指定getter函数的属性会抛出错误。
(myObject, 'a', { value: 4, writable: true, configurable: false,//不可配置 enumerable: true...: Cannot redefine property: a 不管是不是处于严格模式,尝试修改一个不可配置的属性描述符都会出错,即把configurable修改成false是单向操作,无法撤销。...这个方法是应用在对象上的级别最高的不可变性,它会禁止对对象本身以及任意直接属性的修改(这个对象引用的其他对象不受影响)。...如果是,在非严格模式下静默失败,在严格模式下抛出TypeError异常; 3)如果都不是,将该值设置为属性的值。 如果对象中不存在这个属性,[[Put]]操作会更复杂。...1.3.9 Getter 和 Setter 对象默认的 [[Put]] 和 [[Get]]操作分别可以控制属性值的设置和获取。
如果你尝试向不可扩展的对象添加新属性,就会发生这种情况(参见§14.2)。这些方法可能抛出 TypeError 的其他原因与属性本身有关。可写属性控制对值属性的更改尝试。...可配置属性控制对其他属性的更改尝试(并指定属性是否可以被删除)。然而,规则并不完全直观。例如,如果属性是可配置的,那么即使该属性是不可写的,也可以更改该属性的值。...此外,即使属性是不可配置的,也可以将属性从可写更改为不可写。以下是完整的规则。...如果一个属性不可配置,你就无法改变它的可配置或可枚举属性。 如果一个访问器属性不可配置,你就无法更改其 getter 或 setter 方法,也无法将其更改为数据属性。...如果一个数据属性不可配置,你就无法将其更改为访问器属性。 如果一个数据属性不可配置,你就无法将其可写属性从false更改为true,但你可以将其从true更改为false。
target: 需要取值的目标对象 propertyKey: 需要获取的值的键值 receiver: 如果target对象中指定了getter,receiver则为getter调用时的this值。...如果设置的原型不是Object或null,或者被修改的对象的原型不可扩展,则抛出TypeError。...中,它将被强制为不可扩展的普通对象并返回false。...preventExtensions() Object.preventExtensions()返回被设为不可扩展的对象,如果参数不是对象,则在ES5中抛出TypeError,在ES2015中,参数如为不可扩展的普通对象...如果对象已变得不可扩展,则Reflect.preventExtensions() 返回true,否则返回false。如果参数不是对象,则抛出TypeError。
descriptor: 要定义或修改的属性描述符。 属性描述符 对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。...存取描述符是由getter函数和setter函数所描述的属性。一个描述符只能是数据描述符和存取描述符这两者其中之一,不能同时是两者。...属性描述符 configurable enumerable value writable get set 数据描述符 可以 可以 可以 可以 不可以 不可以 存取描述符 可以 可以 不可以 不可以 可以...// Uncaught TypeError: Cannot redefine property: key }); delete obj.key; // configurable为false时不可以删除属性...x of # which has only a getter set 属性的setter函数,如果没有setter,则为undefined。
vue 1.0.18+对Object.freeze()提供了支持,对于data或vuex里使用freeze冻结了的对象,vue不会做getter和setter的转换。...一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。...此外,冻结一个对象后该对象的原型也不能被修改。 但它冻结的是值,你仍然可以将变量的引用替换掉 上面提到的: 可枚举性、可配置性、可写性,以及不能修改已有属性的值 ?...打印输出还是2 ,属性a的值不能被改变 解析:writable:false 可以看作为属性不可改变,在严格模式("use strict";)下,引擎会抛出TypeError的异常,这表示我们无法修改一个不可写的属性...configurable:只要属性是可配置的,就可以使用 defineProperty(...)方法来修改属性描述符 注意⚠️ 在false情况下,如果修改,不管是不是严格模式,都会抛出TypeError
很明显,继承属性和不可枚举属性是不能拷贝的,这一原理其实和JSON.stringify是相同的,返回的都是自身可枚举属性。...这里copy.bar的值来自obj.bar的getter函数的返回值,那么该如何将访问器这类属性描述也拷贝过去呢?...该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。...如果合并源包含getter,这可能使其不适合将新属性合并到原型中。...String类型和 Symbol 类型的属性都会被拷贝。 在出现错误的情况下,例如,如果属性不可写,会引发TypeError,如果在引发错误之前添加了任何属性,则可以更改target对象。
'use strict'; NaN = 3; //TypeError: Cannot assign to read only property 'NaN' of # 给不可写属性赋值,...给只读属性(getter-only)赋值赋值, 给不可扩展对象(non-extensible object)的新属性赋值) 都会抛出异常: "use strict"; // 给不可写属性赋值 var...return 17; } }; obj2.x = 5; // TypeError: Cannot set property x of # which has only a getter...// 给不可扩展对象的新属性赋值 var fixed = {}; Object.preventExtensions(fixed); fixed.newProp = "haha"; // TypeError...: Can't add property newProp, object is not extensible 删除不可删除属性 在严格模式下, 试图删除不可删除的属性时会抛出异常(之前这种操作不会产生任何效果
var great = {} Object.defineProperty(great,'name',{ configurable: false,//设置 name 属性值不可删除 value:...,设置值时触发 set set 指向了 setter方法,get 指向了 getter 方法 约定属性名前面加上 _ 作为私有变量,即外部不可以直接访问,需要通过 get 与 set 来访问,...)//26 getter 与 setter 不一定都要定义,只定义了 get 表示只能读,反之表示只能写 var Great = { _age: 20 } Object.defineProperty...false,writable 为 false;所以不许修改其值 Object.defineProperties(Great,{ name: { writable: false, //将此属性设为不可更改...set 方法都会报错,因为这个 configurable 就是规定每个属性在第一次设置之后是否可以再次修改 Uncaught TypeError: Cannot redefine property
== "function") throw TypeError(); function(){}; f.prototype = p; return new f(); } 五、属性的查询和设置 []...运算符,它使用字符串值(字符串值是动态的,可以在运行时更改) .运算符,它使用标识符(标识符是静态的,必须写死在程序中) var a = {x:1,y:2}; for(item in a){ a.item...a = {p:{x:1}}; delete a.p.x; delete a.p; 某些内置对象是不可配置的,比如通过变量声明和函数声明创建的全局对象的属性: delete Object.prototype...由getter和setter定义的属性称做“存取器属性”,其不同于“数据属性”,数据属性只有一个简单的值。 2....Object.preventExtensions()[不可扩展] -> Object.seal()[不可扩展、自有属性不可配置] -> Object.freeze()[不可扩展、自有属性不可配置、数据属性设置为只读
configurable: true, enumerable: true }); myObject.a = 3; myObject.a; // 2 2.configurable 只要属性是可配置的...myObject.a; // 3 Object.defineProperty(myObject,"a",{ value: 4, writable:true, configurable:false,// 不可配置...1.对象常量,结合writable: false 和configurable: false 就可以创建一个真正的常量属性 (不可修改,重定义或者删除)。... // 2 由于只定义了 a 的getter,所以对a 的值进行设置时set 操作会忽略赋值操作,不会抛出错误。...通常来讲getter 和setter是成对出现的 var myObject = { // 给 a 定义一个getter get a() { return this.
Getter 和 setter在java中被广泛使用。一个好的java编程准则为:将所有属性设置为私有的,同时为属性写getter和setter函数以供外部使用。...这样做的好处是属性的具体实现被隐藏,当未来需要修改时,只需要修改getter 和 setter即可,而不用修改代码中所有引用这个属性的地方。...而不可能触发一个函数的调用。...也就是说,python的对象属性访问的语法,天然就提供了getter和setter的功能。 由于这个区别,我们没有必要在python中为每个对象的属性写getter和setter。...这个函数会检查输入是否为一个字符串,如不是则raise一个TypeError 在获取属性时(代码的最后一行),用于get name的函数被调用 在修改前后,使用Person类的代码完全相同 总结 Python
领取专属 10元无门槛券
手把手带您无忧上云