Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通过setter设置继承的属性_Javascript_Inheritance - Fatal编程技术网

Javascript 通过setter设置继承的属性

Javascript 通过setter设置继承的属性,javascript,inheritance,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} }); // 'Ca

我有以下代码:

// '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设置继承属性是可能的,这意味着我做错了什么。但究竟是什么呢

我希望
myCar.setWheels=2
改变继承的属性,但是它设置了
myCar
的本地属性,而该属性会隐藏继承的属性

好的,您已经“调用”了
myCar
上的setter,因此您正在设置它的
.wheels
属性

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

Car.prototype.setWheels = 2;
(尽管我从未见过有两个轮子的汽车)

请注意,通常您希望实例属性(
.wheels
Vehicle
中设置)仅在实例(如
myCar
)上明显,而不是在原型上。你可以考虑普遍接受的一个。


您在MDN上看到的报价:

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

意味着在没有setter(但它是数据属性或尚未存在)的情况下,将在赋值时生成自己的属性。如果分配给的属性定义了一个setter(自己的或继承的),则将调用该setter函数

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

setter函数做什么是一个完全不同的问题。它可以创建一个属性(就像您的属性一样,通过分配给
.wheels
),或者执行其他任何操作;包括重新定义自己等疯狂的事情

要获得“预期”行为,可以使用局部变量存储控制盘的数量,并使用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
。在
Car
实例上分配给
.wheels
将调用共享setter,它将更新共享变量。请注意,这种行为通常是不可取的,您不希望一个实例影响所有其他实例。

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

您到底想要什么??这段代码在我这边工作得很好。对于myCar,它返回车轮:2;对于new Car,返回车轮:4()。我认为这已经改变了孩子的财产。但不是父母财产。这个问题纯粹是教育问题。我正在学习JavaScript并进行实验。它很可能会给您本地属性“轮子:2”,这与继承的轮子相反。试着用myCar.hasOwnProperty(“车轮”)检查一下。我的问题是关于改变继承价值。同样,这个问题纯粹是教育性的。我在MDN上读到:“将属性设置为对象会创建一个自己的属性。获取和设置行为规则的唯一例外是存在一个带有getter或setter的继承属性。”并尝试对其进行测试。我知道“普遍接受的”继承方式,我只是好奇。是的,你是在说原型的setter。但是,在您的示例中实际存储该值的是
this.wheels=x
——它在当前实例上设置该值。如果您使用一个将其存储在局部变量中的实getter setter属性,则可以从继承getter的所有对象访问该局部变量,并且更改会影响所有对象。“…如果您使用一个将其存储在局部变量中的实getter setter属性…”你能提供一个正确的例子吗?我认为应该创建当前实例的属性,因为如果它更改了基类属性的值,这是它引用的基类变量内存,这将影响车辆类的所有子级。如果我错了,请纠正我,因为我误解了能手和二传手的概念和目的。现在一切都清楚了。准确而完整的答案。谢谢,伙计。