通过setter设置继承的属性

时间:2014-10-15 11:04:37

标签: javascript inheritance

我有这段代码:

// '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的本地属性,阴影继承了它。从我所看到的here设置继承属性通过setter是可能的,这意味着我做错了。但具体到底是什么?

2 个答案:

答案 0 :(得分:2)

  

我希望myCar.setWheels = 2能够改变继承的属性,而是设置myCar的本地属性,其中阴影继承了一个

嗯,你已经被称为" myCar上的setter,因此您要设置其.wheels属性。

如果要更改继承的属性,则需要在继承它的对象上更改它:

Car.prototype.setWheels = 2;

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

请注意,通常您希望实例属性(.wheels中设置的Vehicle)仅在实例(如myCar)上显示,而不是在原型上显而易见。您可以考虑changing your way of inheritance到普遍接受的那个。


您在MDN上阅读的引文:

  

将属性设置为对象会创建自己的属性。唯一的   获取和设置行为规则的例外是有的   带有getter或setter的继承属性。

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

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

setter函数做什么它是一个完全不同的问题。它可以创建一个属性(就像你的那样,通过分配给.wheels on the current instance, this),或做其他事情;包括重新定义自己等疯狂的东西。

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

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。分配到.wheels个实例上的Car将调用共享 setter,后者会更新 shared 变量。请注意,这种行为通常是不受欢迎的,您不希望一个实例影响所有其他实例。

答案 1 :(得分:0)

您创建了新的Vehicle实例,因此您无法直接更改它。 当新的Vehicle返回具有属性轮的对象时,在这里您将其设置为Car.prototype意味着您正在创建一个具有新Vehicle返回的一些原型属性的函数。 所以setWheels属性也会被复制到Car.prototype。 因此,setWheels中的此运算符引用Car,当您使用setWheels设置值时,它会为car创建属性轮(覆盖使用复制/继承属性),因此它显示轮是Car的属性。尝试在setWheels设置值之前和之后控制myCar.hasOwnProperty(" wheels")。