简体   繁体   English

是否可以确定是否从原型方法中调用了实例方法?

[英]Is it possible to determine whether an instance method was called from within a prototype method?

function Foo(x) {
    this.bar = function() { return x; /* but not always */ }
}

Foo.prototype.baz = function() {
    return this.bar(); // Case 2 - should return x
};

var f = new Foo(3);
f.bar(); // Case 1 - should return undefined 
f.baz(); // should return x which is 3 in this case

So, bar is an instance method of f which is an instance of Foo . 因此, barf的实例方法,它是Foo的实例。
On the other hand, baz is a prototype method of Foo . 另一方面, bazFoo的原型方法。

What I would like is this: 我想要的是这样的:

bar should return x (the argument passed into the constructor function), but only if it is called from within a prototype method (a method of Foo.prototype ). bar应该返回x (传递给构造函数的参数),但Foo.prototype是必须从原型方法( Foo.prototype方法)中调用x So, bar should check whether the current execution context is a Foo.prototype function, and only then bar should return x . 因此, bar应该检查当前执行上下文是否是Foo.prototype函数,然后bar应该返回x

In Case 1, the current execution context is Global code, so the return value of the bar call should be undefined . 在情况1中,当前执行上下文是Global代码,因此bar调用的返回值应为undefined (By this, I mean: I want it to return undefined in this case.) (通过这个,我的意思是:在这种情况下,我希望它返回未定义的。)

However in this case 2, the current execution context is Function code of a Foo.prototype function, so the return value of the bar call should be x . 但是,在这种情况2下,当前执行上下文是Foo.prototype函数的Function代码,因此bar调用的返回值应为x

Can this be done? 能做到吗?


Update: A real-world example: 更新:真实示例:

function Foo(x) {
    this.getX = function() { return x; /* but not always */ }
}

Foo.prototype.sqr = function() {
    var x = this.getX(); // should return 3 (Case 2)
    return x * x;
};

var f = new Foo(3);
f.getX(); // should return undefined (Case 1)
f.sqr(); // should return 9

Case 1: getX is called "directly" -> return undefined 情况1: getX被称为“直接”->返回未定义
Case 2: getX is called from within a prototype method -> return x 情况2:从原型方法中调用getX > return x

In Case 1, the current execution context is Global code, so the return value of the bar call should be undefined. 在情况1中,当前执行上下文是全局代码,因此bar调用的返回值应未定义。

you're using a closure, that is why the method getX has acces to the variable x. 您正在使用闭包,这就是为什么getX方法访问变量x的原因。 It's javascript behaving as intended. 它的javascript行为符合预期。

So this is my own solution: 所以这是我自己的解决方案:

function Foo(x) {
    function getX() { 
        return getX.caller === Foo.prototype.sqr ? x : void 0;
    }
    this.getX = getX;
}

Foo.prototype.sqr = function() {
    var x = this.getX();
    return x * x;
};

var f = new Foo(3);
console.log( f.getX() ); // logs undefined 
console.log( f.sqr() ); // logs 9

As you can see, I had to define getX as a local function of the Foo constructor (and then assign this function to the instance via this.getX = getX; . Inside getX , I explicitly check whether getX.caller is Foo.prototype.sqr . 如您所见,我必须将getX定义为Foo构造函数的本地函数(然后通过this.getX = getX;将此函数分配给实例。在getX ,我明确检查getX.caller是否为Foo.prototype.sqr

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

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