Javascript可写描述符是否会阻止实例的更改? [英] Does Javascript writable descriptor prevent changes on instances?

查看:148
本文介绍了Javascript可写描述符是否会阻止实例的更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

答案(请在下面阅读,各自的作者提供了宝贵的见解):

Answers (please read them below, their respective authors provided valuable insights):


  • 可写: false阻止分配新值,
    Object.defineProperty不是分配操作,因此
    忽略可写的值

  • 属性属性
    是继承的,因此在每个
    子类/实例上,属性将保持不可写,直到一个子类(或子类的实例)将writable的值更改为true为自身

问题

有关该物业的MDN文件可写描述符状态:

MDN documentation concerning the property "writable" descriptor states:


可写
当且仅当与属性关联的值可能通过赋值更改时才为真运营商。
默认为false。

writable true if and only if the value associated with the property may be changed with an assignment operator. Defaults to false.

官方ECMA-262第6版或多或少表示相同。
意思很清楚,但根据我的理解,它仅限于原始财产(即该特定对象的财产)

The official ECMA-262 6th edition more or less states the same. The meaning is clear but, to my understanding, it was limited to the original property (i.e. the property on that specific object)

但是,请考虑以下示例( JSFiddle ):

However, please consider the following example (JSFiddle):

//works as expected, overloading complete       
var Parent = function() {};
Object.defineProperty(Parent.prototype, "answer", {
    value: function() { return 42; }
});

var Child = function() {};
Child.prototype = Object.create(Parent.prototype, {
    answer: {
        value: function() { return 0; }
    }
});

var test1 = new Parent();
console.log(test1.answer()); //42
var test2 = new Child();
console.log(test2.answer()); //0

//does not work as expected
var Parent2 = function() {};
Object.defineProperty(Parent2.prototype, "answer", {
    value: function() { return 42; }
});

var Child2 = function() {};
Child2.prototype = Object.create(Parent2.prototype);

test3 = new Parent2();
console.log(test3.answer()); //42
test4 = new Child2();
test4.answer = function() { return 0; };
console.log(test4.answer()); //42

按照这个例子,我们看到,尽管该属性不可写,但它可以是像我期望的那样在子类(test2)的原型上重载。

Following this example, we see that, although the property is not writable, it can be overloaded on the prototype of a subclass (test2), as I would expect.

然而,当尝试在子类的实例(test4)上重载方法时,它无声地失败。我原以为它可以像test2一样工作。尝试在Parent的实例上重载属性时也会发生同样的情况。

However, when trying to overload the method on an instance of a subclass (test4), it fails silently. I would have expected it to work just as test2. The same happens when trying to overload the property on an instance of Parent.

同样的事情发生在NodeJS和JSFiddle中,并且在某些情况下,实例上的重载会抛出关于该属性的只读性质的TypeError。

The same thing occurs in both NodeJS and JSFiddle and, under some conditions, overloading on the instance throws a TypeError concerning the readonly nature of the property.

您能否向我确认这是预期的行为?如果是,那么解释是什么?

Could you please confirm to me that this is the expected behaviour ? If so, what is the explanation ?

推荐答案

是的,这是预期的行为。

Yes, this is expected behaviour.


它无声地失败。

it fails silently.

不完全是。或者:仅在草率模式下。如果您 use strict模式,你会得到一个

Not exactly. Or: Only in sloppy mode. If you "use strict" mode, you'll get an

Error { message: "Invalid assignment in strict mode", … }

test4.answer = function(){返回0; };


它可以在子类(test2)的原型上重载,但不是一个实例子类(test4)

it can be overloaded on the prototype of a subclass (test2), but not an instance of a subclass (test4)

这与实例与原型无关。您没有注意到的是您使用不同的方法来创建重载属性:

This has nothing to do with instances vs. prototypes. What you didn't notice is that you're using different ways to create the overloading property:


  • 对属性的赋值< a href =https://stackoverflow.com/a/29608794/1048572>继承和不可写失败

  • 一个 Object.defineProperty 调用只是创建一个新属性,除非该对象是不可扩展的

  • an assignment to a property that is inherited and non-writable fails
  • an Object.defineProperty call just creates a new property, unless the object is non-extensible

你也可以这样做你的实例:

You can do the same for your instance:

Object.defineProperty(test4, "answer", {
    value: function() { return 42; }
});

这篇关于Javascript可写描述符是否会阻止实例的更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆