我尝试了一些事情,它满足了80%的需求,但还不够用。
// Different file
function A(){}
A.prototype.ao = function(){
// Here I want ot know the fucntion caller class name, for that I used
arguments.callee.caller.prototype; // It retuens B.bo {} (object)
}
// Different file
function B(){}
B.prototype.bo = function(){
var a = new A();
a.ao();
}
如何从调用者原型中检索类名,因为它是object类型。
如果我们能够获得调用者函数上下文,我会更有帮助。
答案 0 :(得分:3)
如何从调用者原型
中检索类名
你不能*,原因有两个:
函数没有name
属性。 They will in ES6,但他们还没有。 (不过,您可以使用名称为B
分配属性。)
虽然你可以获得B.prototype.bo
上的函数的引用,但是没有从那里回到B
的链接。联系是单向的。 (尤其是因为相同的功能可以在多个对象上。)
请注意,使用arguments.callee
强烈建议不要,并且在严格模式下禁止使用caller
,并且不鼓励使用A.prototype.ao = function(){
try {
throw new Error();
}
catch (e) {
// Examine e.stack here
}
};
特别。几乎总有一种更好的方法来做你想要做的事情。
*在某些引擎上,您可以从调用堆栈中找出它,例如:
B
您将依赖特定于平台的命名等。
但同样,几乎肯定有一个更好的选择,而不是试图知道谁在打电话给你。
重新评论:
这里我的要求是跟踪API函数的使用情况,为了实现它我遵循这种方式......而且我不能改变现有的框架。
你可能会但却没有意识到,因为JavaScript强大 。 : - )
例如:一旦在页面上加载任何框架创建B.prototype
,这里的代码将用function wrapFunctions(name, proto) {
Object.keys(proto).forEach(function(key) {
var original = proto[key];
if (typeof original === "function") {
proto[key] = function() {
var rv;
starting(name, key); // <=== Your function to tracking the start of a call
rv = original.apply(this, arguments);
stopping(name, key); // <=== Your function tracking the end of the call
return rv;
};
}
});
}
wrapFunctions("B", B.prototype);
上的每个函数包装一个告诉你它正在运行的版本:
// The framework
function B() {}
B.prototype.f1 = function() {
snippet.log("Original functionality for f1");
};
B.prototype.f2 = function() {
snippet.log("Original functionality for f2");
};
B.prototype.f3 = function() {
snippet.log("Original functionality for f3 -- calling f2");
this.f2();
snippet.log("Original functionality for f3 -- done calling f2");
};
// Let's use f1 and f2 before we wrap them
snippet.log("Before wrapping:");
var b1 = new B();
b1.f1();
b1.f2();
b1.f3();
// Now your code runs and wraps them
wrapFunctions("B", B.prototype);
// Now let's use f1 and f2 again
snippet.log("After wrapping:");
var b2 = new B();
b2.f1();
b2.f2();
b1.f3();
// Our function to track that a call started
function starting(ctor, name) {
snippet.log(ctor + "#" + name + ": Started");
}
// Our function to track that a call stopped
function stopping(ctor, name) {
snippet.log(ctor + "#" + name + ": Stopped");
}
// Our function to wrap things
function wrapFunctions(name, proto) {
Object.keys(proto).forEach(function(key) {
var original = proto[key];
if (typeof original === "function") {
proto[key] = function() {
var rv;
starting(name, key); // <=== Your function to tracking the start of a call
rv = original.apply(this, arguments);
stopping(name, key); // <=== Your function tracking the end of the call
return rv;
};
}
});
}
这是“仪器仪表”的开始。但请注意,有适当的库可以解决边缘情况等问题。
直播示例:
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
{{1}}
答案 1 :(得分:0)
您可以在返回其类型的对象中包含一个方法。另一个选择是使用instanceof
并检查所有可能的类型。
function A() {
this.getType = function () {
return "A";
}
}
A.prototype.ao = function() {
// Here I want ot know the fucntion caller class name, for that I used
var type = this.getType();
args.callee.caller.prototype; // It retuens B.bo {} (object)
}
function B(){
this.getType = function () {
return "B";
}
}
B.prototype.bo = function(){
var a = new A();
a.ao.apply(this);
}
在这里,您还必须在所有继承的类型中重新定义getType
并返回正确的类型。您还需要使用apply(this)
调用所需的方法来提供当前调用者的上下文。