简体   繁体   English

在另一个对象中调用另一个对象的方法

[英]Call another object's method in another object

How does one call another object's method in the current method? 一个人如何在当前方法中调用另一个对象的方法?

Example: 例:

function OjbectA() {}

ObjectA.prototype.doWork = function () {
  alert('do work');
}

var objectA = new ObjectA();

function ObjectB() {}

ObjectB.prototype.method = function() {

   // How to call Object A's doWork() method
}

Current attempt: 当前尝试:

// Call doWork
ObjectA.doWork();

Error: "Type Error: doWork() function is not defined. 错误:“类型错误:doWork()函数未定义。

Question: 题:

What is the correct way to call the method of another object WITHIN the method. 在方法内调用另一个对象的方法的正确方法是什么。 What about scoping? 范围界定呢?

Does ObjectA have to instantiated to call it's methods? 是否必须实例化ObjectA才能调用它的方法?

What about the apply() or call() method? apply()call()方法呢? I am confused how they apply in this situation. 我很困惑它们在这种情况下的应用。

Final remarks 结束语

I want to thank everyone's input in advance. 我要先感谢大家的投入。 I have only recently made the dive into javascript's OOP. 我只是最近才跳入javascript的OOP。 This seemingly simple question is something that I have been struggling all day and I came on here as a final resort. 这个看似简单的问题是我整天都在苦苦挣扎的事情,我来到这里是最后的手段。

There is a typo, not ObjectA.doWork(); 有一个错字,不是ObjectA.doWork(); use objectA.doWork(); 使用objectA.doWork();

What is the correct way to call the method of another object WITHIN the method. 在方法内调用另一个对象的方法的正确方法是什么。 What about scoping? 范围界定呢?

There is no one "correct" way. 没有一种“正确”的方法。 Presumably you want to be able to call a method of ObjectA instances (ie a method of ObjectA.prototype ) but have an instance of ObjectB as this , so: 想必你希望能够调用对象A的实例的方法(即ObjectA.prototype的方法),但有对象B的实例作为这一点 ,所以:

ObjectB.prototype.method = function() {

    // How to call Object A's doWork() method
    ObjectA.prototype.doWork.call(this);
}

That will call the method and set the instance of ObjectB as this . 这将调用该方法并将ObjectB的实例设置为this

Does ObjectA have to instantiated to call it's methods? 是否必须实例化ObjectA才能调用它的方法?

If you mean "does and instance of ObjectA have to instantiated to call its methods" then no, as shown above. 如果您的意思是“必须实例化ObjectA的实例和实例才能调用其方法”,则否,如上所示。 You can call the method on the constructor's prototype directly. 您可以直接在构造函数的原型上调用该方法。

What about the apply() or call() method? 那apply()或call()方法呢? I am confused how they apply in this situation. 我很困惑它们在这种情况下的应用。

See the answer to the first question. 请参阅第一个问题的答案。 Whether to use call or apply depends on the arguments that need to be passed and whether you intend do to any processing on them first. 是否使用callapply取决于需要传递的参数,以及是否打算首先对其进行任何处理。

Additional answers 其他答案

Could you explain the mechanics of ObjectA.prototype.doWork.call(this) a little more? 您能否再解释一下ObjectA.prototype.doWork.call(this)的机制?

It calls the method and sets its this to the supplied object. 它调用该方法,并将其向所提供的对象。 The rules for how a value is assigned to this are explained in EMCA–2626 §10.4.3 . 一个值是如何分配给规则的解释EMCA-2626§10.4.3

Would ObjectA.prototype.doWork(this) work just the same way? ObjectA.prototype.doWork(this)是否会以相同的方式工作?

No. That calls the function, sets its this to ObjectA.prototype and supplies the value of this from the calling execution context as the first parameter. 号调用该函数,将它的 ObjectA.prototype从作为第一个参数调用执行上下文提供的这个值。 eg if it's global code in a browser, effectively: 例如,如果它是浏览器中的全局代码,则有效地:

ObjectA.prototype.doWork(window);

It's possible to call it from the prototype directly. 可以直接从原型中调用它。

Using apply changes the value of this in the execution of the function to the supplied value, so its essentially forwarding this to be itself in the call. 使用应用更改的值this在功能所提供的值的执行,所以它本质上转发this是自己在电话。 You could also use call , the difference is just in how it takes its arguments, apply takes an array whereas call takes an argument list. 您还可以使用call ,不同之处仅在于它接受参数的方式,apply接受数组而call接受参数列表。

ObjectB.prototype.method = function() {
  ObjectA.prototype.doWork.apply(this);
}

However of course an ObjectB does not necessarily have same properties as an ObjectA so make sure you write the method as generic as possible. 但是,当然, ObjectB不一定具有与ObjectA相同的属性,因此请确保您编写的方法尽可能通用。 In order words use a documented concept rather than internal implementation details. 为了方便起见,请使用书面概念,而不是内部实现细节。

Example again lies with how Array, it's generically applicable methods are documented as such and states what is required for it to work. 例子还是Array的方法,它是一般适用的方法,并说明了其工作所需的条件。

In the case you just want to expose a 'utility function', just put it on the object itself. 如果您只想公开一个“实用功能”,只需将其放在对象本身上即可。 eg 例如

ObjectA.doWork = function(obj) {
};

There really seems to be some confusion with JavaScript's general OOP model. JavaScript的通用OOP模型似乎确实有些混乱。

Every function has an underlying prototype , which is just an object. 每个函数都有一个基础prototype ,它只是一个对象。 You may or may not add anything to it, but if you do, you probably plan to use that function as a constructor . 您可能会或可能不会添加任何内容,但是如果这样做,则可能打算将该函数用作constructor That's what you see happening here: 这就是您在这里看到的情况:

function ObjectA() {}

ObjectA.prototype.doWork = function () {
  alert('do work');
}

var objectA = new ObjectA();

objectA.doWork();

However, in some instances, it might be more appealing to just create a function with some methods directly attached to it, rather than creating instances of it. 但是,在某些情况下,仅创建直接附有某些方法的函数而不是创建其实例可能会更有吸引力。 Generally, these would be static methods as in other languages, or perhaps your function is really just a singleton object. 通常,这些将是其他语言中的静态方法,或者也许您的函数实际上只是一个单例对象。 In this case, you would omit the prototype , and just attach directly, like so: 在这种情况下,您将省略prototype ,而直接附加,如下所示:

function ObjectA() {}

ObjectA.doWork = function () {
  alert('do work');
}

ObjectA.doWork()

Going back to the first example, if you define your function and add methods to its prototype , occasionally you may wish to actually call a function that you have defined in a different function's prototype . 回到第一个示例,如果您定义函数并向其prototype添加方法,则有时您可能希望实际调用在其他函数的prototype定义的函数。 call and apply can be used to call any function with the value of this changing to the object which you pass into apply or call . callapply可以用来调用任何函数的值, this变化给你传递给该对象applycall

Remember that you are attaching methods to the prototype , so it may look a little funky, but here's an example: 请记住,您正在将方法附加到prototype ,所以看起来可能有点时髦,但这是一个示例:

function ObjectA() {}

ObjectA.prototype.doWork = function () {
    console.log(this)
}

var objectA = new ObjectA();

function ObjectB() {}

ObjectB.prototype.method = function() {

   ObjectA.prototype.doWork.call(this);
}

var objectB = new ObjectB();

objectB.method() 

// -> objectB will be logged to your console, bc 
// it became the value of this in ObjectA's doWork method.

After all I found your typo: 毕竟我发现了您的错字:

function OjbectA() {}

Should be function ObjectA() {} 应该是function ObjectA() {}

That's why you were facing error. 这就是为什么您遇到错误。


function ObjectA() {}

ObjectA.prototype.doWork = function () {
  alert('do work');
}

var objectA = new ObjectA();

function ObjectB() {}

ObjectB.prototype.method = function() {

   objectA.doWork()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM