在下面的代码段中,为什么我呼叫Document
时boat.calls
会增加?另外,为什么只调用一次getHasEngine()后sailboat.getHasEngine()
设置为2?
sailboat.calls
答案 0 :(得分:5)
由于getHasEngine
中的这一行:
vehicle.calls = vehicle.calls + 1;
那是直接访问vehicle
对象。由于boat
没有自己的calls
属性,因此它是从vehicle
继承的,因此boat.calls
为1。
还有,为什么只调用一次
sailboat.calls
后getHasEngine()
设置为2?
也因为该行:将vehicle.calls
设置为1
,并且此时sailboat
没有自己的calls
,因此它继承了该属性。然后在下一行执行以下操作:
this.calls = this.calls + 1;
正在读取 vehicle.calls
(1),向其添加1,然后将结果(2)分配给sailboat.calls
。
让我们扔一些ASCII艺术。创建对象之后但在调用getHasEngine
之前,您已经在内存中保存了此信息(省略了详细信息):
+−−−−−−−−−−+ vehicle−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−−>| (object) | | +−−−−−−−−−−+ | | calls: 0 | | +−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | boat−−−−−−−−−−−−−−−−−−−−−−−−−−−+−−>| (object) | | | +−−−−−−−−−−−−−−−+ | | | [[Prototype]] |−−+ | +−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−+ | sailboat−−−>| (object) | | +−−−−−−−−−−−−−−−+ | | [[Prototype]] |−−+ +−−−−−−−−−−−−−−−+
请注意,boat
和sailboat
都没有calls
属性。
调用一次getHasEngine
之后,您将具有以下条件-请注意,sailboat
现在具有calls
属性(因为它是由this.calls = this.calls + 1;
创建的):
+−−−−−−−−−−+ vehicle−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−−>| (object) | | +−−−−−−−−−−+ | | calls: 1 | | +−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | boat−−−−−−−−−−−−−−−−−−−−−−−−−−−+−−>| (object) | | | +−−−−−−−−−−−−−−−+ | | | [[Prototype]] |−−+ | +−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−+ | sailboat−−−>| (object) | | +−−−−−−−−−−−−−−−+ | | [[Prototype]] |−−+ | calls: 2 | +−−−−−−−−−−−−−−−+
以下是带有一些日志记录的版本,以帮助您了解一下:
let vehicle = {
calls: 0,
hasEngine: null,
getHasEngine: function() {
console.log("updating vehicle.calls");
vehicle.calls = vehicle.calls + 1;
console.log("vehicle.calls is now vehicle.calls");
console.log("About to update this.calls, does this have calls?", this.hasOwnProperty("calls"));
this.calls = this.calls + 1;
console.log("Just updated this.calls, does this have calls?", this.hasOwnProperty("calls"));
return this.hasEngine;
},
canFly: null,
getCanFly: function() {
vehicle.calls = vehicle.calls + 1;
this.calls = this.calls + 1;
return this.canFly;
}
}
let boat = Object.create(vehicle);
boat.canFly = false;
let sailboat = Object.create(boat);
sailboat.hasEngine = false;
let fishingBoat = Object.create(boat);
fishingBoat.hasEngine = true;
console.log(vehicle.calls); // 0
console.log(boat.calls); // 0
console.log("boat has calls?", boat.hasOwnProperty("calls"));
console.log(sailboat.calls); // 0
console.log("sailboat has calls?", sailboat.hasOwnProperty("calls"));
sailboat.getHasEngine();
console.log(vehicle.calls); // 1
console.log(boat.calls); // 1
console.log("boat has calls?", boat.hasOwnProperty("calls"));
console.log(sailboat.calls); // 2
console.log("sailboat has calls?", sailboat.hasOwnProperty("calls"));
.as-console-wrapper {
max-height: 100% !important;
}
如果删除vehicle.calls =
行,则会看到它停止发生:
let vehicle = {
calls: 0,
hasEngine: null,
getHasEngine: function() {
//vehicle.calls = vehicle.calls + 1;
this.calls = this.calls + 1;
return this.hasEngine;
},
canFly: null,
getCanFly: function() {
//vehicle.calls = vehicle.calls + 1;
this.calls = this.calls + 1;
return this.canFly;
}
}
let boat = Object.create(vehicle);
boat.canFly = false;
let sailboat = Object.create(boat);
sailboat.hasEngine = false;
let fishingBoat = Object.create(boat);
fishingBoat.hasEngine = true;
console.log(vehicle.calls); // 0
console.log(boat.calls); // 0
console.log(sailboat.calls); // 0
sailboat.getHasEngine();
console.log(vehicle.calls); // 0
console.log(boat.calls); // 0
console.log(sailboat.calls); // 1