通过setter设置继承的属性 [英] Setting inherited property via setter

查看:139
本文介绍了通过setter设置继承的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这段代码:

// 'Vehicle' object constructor
function Vehicle() {
  this.wheels = 4;
}

// Adding 'setWheels' setter function to set 'wheels' property
Object.defineProperty(Vehicle.prototype, "setWheels", {
  set: function(x) {this.wheels = x}
});

// 'Car' object constructor with 'Vehicle' as prototype
function Car() {}
Car.prototype = new Vehicle;
Car.prototype.constructor = Car;

// myCar inherits 'wheels' property and 'setWheels' method
myCar = new Car();

myCar.setWheels = 2;

我原以为 myCar.setWheels = 2 改变继承的属性,但它设置myCar的本地属性,阴影继承了一个。从我读过的这里通过setter设置继承的属性是可能的,这意味着我做错了什么。但究竟是什么?

I was expecting myCar.setWheels = 2 to alter the inherited property, but instead it sets myCar's local property which shadows inherited one. From what I have read here setting inherited property via setter is possible, which means I am doing something wrong. But what exactly?

推荐答案


我原以为 myCar.setWheels = 2 来改变继承的属性,而是设置 myCar 的本地属性,其中shadow继承了一个

I was expecting myCar.setWheels = 2 to alter the inherited property, but instead it sets myCar's local property which shadows inherited one

嗯,你已经调用 myCar 上的setter,所以你要设置它的。 wheel property。

Well, you've "called" the setter on myCar, so you are setting its .wheels property.

如果你想改变继承的属性,你需要在继承它的对象上改变它:

If you wanted to alter the inherited property, you need to alter it on the object from which it is inherited:

Car.prototype.setWheels = 2;

(虽然我从未见过有两个轮子的车)

请注意,通常你会期望实例属性( .wheels 设置在 Vehicle )仅在实例上显而易见(例如 myCar ),而不是在原型上。您可以考虑改变您的继承方式到普遍接受的方式。

Notice that usually you'd expect instance properties (.wheels set in Vehicle) to be only apparent on instances (like myCar), not on prototypes. You might consider changing your way of inheritance to the commonly accepted one.

您在MDN上阅读的报价:

The quote you have read at MDN:


将属性设置为对象创造一个自己的财产。获取和设置行为规则的唯一
异常是当
是带有getter或setter的继承属性时。

Setting a property to an object creates an own property. The only exception to the getting and setting behavior rules is when there is an inherited property with a getter or a setter.

表示当 no setter (但它是数据属性或尚未存在)时,将在赋值时生成自己的属性。如果被分配的属性定义了一个setter(自己的或继承的),那么将调用 setter函数

means that an own property will be generated on assignment when there is no setter (but it is a data property or not existing yet). If the property that gets assigned to has a setter defined (either own or inherited), then that setter function will be invoked instead.

确实,在您的示例中,没有在 myCar 上创建自己的 .setWheels 属性。

Indeed, in your example, no own .setWheels property is getting created on your myCar.

setter函数做什么它是一个完全不同的问题。它可以创建一个属性(就像你的那样,通过分配给 .wheels 在当前实例上, ),或做其他事情;包括像重新定义自身这样的疯狂事情。

What the setter function does it a whole different question. It can create a property (like yours does, by assigning to .wheels on the current instance, this), or do anything else; including crazy things like redefining itself.

要获得预期行为,您可以使用局部变量来存储轮数并使用setter / getter属性它:

To get the "expected" behaviour, you could use a local variable to store the number of wheels and use a setter/getter property for it:

function Car() {}
var w = 4; // "local", could be in an IIFE
Object.defineProperty(Car.prototype, "wheels", {
  set: function(x) {
    w = x; // no property changes/creations involved
  },
  get: function() {
    return w;
  }
});

// yourCar inherits 'wheels'
var yourCar = new Car();
yourCar.wheels; // 4
yourCar.wheels = 2; // you've got an odd car

var myCar = new Car();
myCar.wheels; // 2 - what's wrong with my car?!

这里只有一个属性 - Car.prototype.wheels 。分配到 Car 实例上的 .wheels 将调用 shared setter,它将更新共享变量。请注意,这种行为通常是不受欢迎的,您不希望一个实例影响所有其他实例。

Here, there is only one property - Car.prototype.wheels. Assigning to .wheels on the Car instances will call the shared setter, which updates the shared variable. Notice that such behaviour is usually undesirable, you don't want one instance affect all others.

这篇关于通过setter设置继承的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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