【问题标题】:How do I access a member of the same javascript object?如何访问同一 javascript 对象的成员?
【发布时间】:2018-06-16 22:54:54
【问题描述】:

假设我有以下对象定义:

var car = function (engine) { 
    this.engine = engine;

    this.calculateSpeed = function () {
        return engine.power * 20;
    };
};

calculateSpeed() 函数中的engine 对象是指通过构造函数传入的引擎对象,而不是汽车的公共引擎成员(这是我想要的)。

如果我想在创建汽车对象后更改汽车的引擎,我希望 calcuateSpeed() 函数引用新引擎。

Inner function cannot access outer functions variable 的问题与我的类似。但并没有完全涵盖我的用例,因为 OP 使用的是局部变量并且没有构造函数。

如果您还可以解释为什么这不起作用,那也会有很大帮助:

var car = function (engineInit) { 
    this.engine = engineInit;

    this.calculateSpeed = function () {
        return engine.power * 20;
    };
};

我知道对于这个简单的示例,我可以使用this.calculateSpeed = engine.power * 20;,但对于我的实际用例,我需要一个函数。

【问题讨论】:

  • 您在使用this.engine.power时遇到什么问题?
  • 正如我在问题中提到的,this.engine.power 的范围是 calculateSpeed 函数而不是汽车对象。
  • @StormMuller 不确定我同意。你检查我的答案了吗?
  • @user3210641 是的,你是对的。似乎我遇到了关闭问题。我接受了 Josh 的回答,因为它回答了我发布的问题。还帮助我避免了关闭问题。

标签: javascript object scope


【解决方案1】:

您实际上可以使用this.engine.power

// Define Car constructor
const Car = function (engineInit) { 
    this.engine = engineInit;

    this.calculateSpeed = function () {
        return this.engine.power * 20;
    };
};

// Create new car instance
const carInstance = new Car({ power: 100 });

// Log the result of calculateSpeed function
console.log(carInstance.calculateSpeed());

【讨论】:

  • @Musa 你为什么编辑答案?或者更准确地说,你为什么要添加不相关的代码?
  • 显示在计算中使用的引擎不是构造函数中传递的引擎。如果编辑有误,您可以随时撤消它。
  • 如果calculateSpeed 有一个本地的engine 变量,this 关键字的行为会如何?
【解决方案2】:

如果您希望内部engine 与在实例化Car 外部可见的engine 属性分开,您可以考虑简单地使用另一个本地范围变量,与初始engine 参数分开,并根据需要重新分配:

var Car = function(initialEngine) {
  this.engine = initialEngine;
  let engine = initialEngine;
  this.calculateSpeed = function() {
    return engine.power * 20;
  };
  this.changeEngine = function(newEngine) {
    engine = newEngine;
  }
};

var car = new Car({ power: 20 });
console.log(car.calculateSpeed());
car.changeEngine({ power: 40 });
console.log(car.calculateSpeed());

【讨论】:

  • 现在将console.log(car.engine.power); 添加到最后一行。汽车的引擎没有改变。
  • 我以为您说您出于某种原因希望它们有所不同? refers to the engine object passed in via the constructor and not the car's public engine member(which is the one I want).如果你真的想分配给实例化对象的属性,只需照常分配,this.engine = newEngine
【解决方案3】:

这个问题与 stackoverflow 上的许多其他问题重复,但无论如何这里有一些东西可以帮助您入门。

通过在另一个变量中捕获它:

var car = function(engineInit) { 
  this.engine = engineInit;
  var self = this;
  this.calculateSpeed = function () {
    return self.engine.power * 20;
  };
};

通过使用绑定:

var car = function(engineInit) { 
  this.engine = engineInit;
  this.calculateSpeed = function () {
    return this.engine.power * 20;
  }.bind(this);
};

通过使用函数的原型:

function Car(engine) { 
  this.engine = engine;
}

Car.prototype.calculateSpeed = function() {
  return this.engine.power * 20;
};

var engine = new Engine();
var car = new Car(engine);
var speed = car.calculateSpeed();

【讨论】:

  • 很酷,谢谢乔希,您能否将重复的内容添加到我的问题中,以便其他来这里的人也可以看到它们?我也喜欢var self = this 解决方案。 Bind 正在改变本地函数的范围,这看起来像是代码异味,原型解决方案意味着我的对象存在于 2 个地方,这也不理想。谢谢!
  • 原型实际上是您的最佳选择,因为您只能创建一次 calculateSpeed 函数。在所有其他实例中(包括我的回答中提到的那个),每次创建新 Car 实例时都会创建新函数。
猜你喜欢
  • 2012-06-13
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多