最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript - get class owner of a function(method) - Stack Overflow

programmeradmin5浏览0评论

there is a way to know what class own a function? Example:

function globalFunc(){
 //alert MyObject
}

function MyObject(){
}
MyObject.prototype.test=function(){
 globalFunc();
}

var o=new MyObject();
o.test();  //alert MyObject

Now im using this workaround:

function globalFunc(){
 alert(globalFunc.caller.__class__);
}

function MyObject(){
}
MyObject.prototype.test=function(){
 globalFunc();
}
MyObject.prototype.test.__class__=MyObject;

var o=new MyObject();
o.test();  //alert MyObject

But there is a big problem, look this:

function globalFunc(){
 alert(globalFunc.caller.__class__);
}

function MyObject(){
}
MyObject.prototype.test=function(){
 var temp=function(){
  globalFunc();
 }
 temp(); 
    /* to simulate a simple closure, this may be for example:
     element.addEventListener("click",temp,false);
    */
}
MyObject.prototype.test.__class__=MyObject;

var o=new MyObject();
o.test();  //alert undefined

So, there is a clear way to obtain this? I know where is the problem(class property is a property of only test and not temp), but i can't add class to temp too.

Thanks.


Thanks for reply, some clarification.

Im trying to do a personal framwork OO oriented with private members.

So:

globalFunc is a special function, im using it to get "private" property and i can't call it with call method or passing some arguments, the only arguments im pass is "this":

Example, $() is global

Class({
    public:{
        MyClass:function(){
        },

        setName:function(name) {
            $(this).name=name; //set the private var name
        },
        getName:function(){
            return $(this).name;
        }
    },
    private:{
        name:"UNKNOWN"
    }
})

var o=new MyClass();
o.getName(); // UNKNOWN
o.setName("TEST!!!");
o.getName(); // TEST!!!
o.name; //undefined
$(o).name; //undefined

To works with inheritance, $(), i need to know what class call it and the object of the class.

All works good, but if i need to access a private members in a clousure i must add __class__ property to clouser!! And i not want this!

Thanks again and sorry for my bad english, im not native speaker.

there is a way to know what class own a function? Example:

function globalFunc(){
 //alert MyObject
}

function MyObject(){
}
MyObject.prototype.test=function(){
 globalFunc();
}

var o=new MyObject();
o.test();  //alert MyObject

Now im using this workaround:

function globalFunc(){
 alert(globalFunc.caller.__class__);
}

function MyObject(){
}
MyObject.prototype.test=function(){
 globalFunc();
}
MyObject.prototype.test.__class__=MyObject;

var o=new MyObject();
o.test();  //alert MyObject

But there is a big problem, look this:

function globalFunc(){
 alert(globalFunc.caller.__class__);
}

function MyObject(){
}
MyObject.prototype.test=function(){
 var temp=function(){
  globalFunc();
 }
 temp(); 
    /* to simulate a simple closure, this may be for example:
     element.addEventListener("click",temp,false);
    */
}
MyObject.prototype.test.__class__=MyObject;

var o=new MyObject();
o.test();  //alert undefined

So, there is a clear way to obtain this? I know where is the problem(class property is a property of only test and not temp), but i can't add class to temp too.

Thanks.


Thanks for reply, some clarification.

Im trying to do a personal framwork OO oriented with private members.

So:

globalFunc is a special function, im using it to get "private" property and i can't call it with call method or passing some arguments, the only arguments im pass is "this":

Example, $() is global

Class({
    public:{
        MyClass:function(){
        },

        setName:function(name) {
            $(this).name=name; //set the private var name
        },
        getName:function(){
            return $(this).name;
        }
    },
    private:{
        name:"UNKNOWN"
    }
})

var o=new MyClass();
o.getName(); // UNKNOWN
o.setName("TEST!!!");
o.getName(); // TEST!!!
o.name; //undefined
$(o).name; //undefined

To works with inheritance, $(), i need to know what class call it and the object of the class.

All works good, but if i need to access a private members in a clousure i must add __class__ property to clouser!! And i not want this!

Thanks again and sorry for my bad english, im not native speaker.

Share Improve this question edited Jun 7, 2011 at 13:17 Nick Craver 631k138 gold badges1.3k silver badges1.2k bronze badges asked Oct 13, 2009 at 12:50 user189086user189086 1
  • You'll have to unlearn the idea that there is such a thing as a "class" in JavaScript. There ain't. – Jonathan Feinberg Commented Oct 13, 2009 at 13:20
Add a ment  | 

7 Answers 7

Reset to default 3

In javascript there are no Classes. Instead several objects can "own" the same function. For example:

function myFun(){
  alert(this.name);
}

function Obj1(){
  this.name = "obj1";
}
Obj1.prototype.fun = myFun;

function Obj2(){
  this.name = "obj2";
}
Obj2.prototype.fun = myFun;
var obj1 = new Obj1();
var obj2 = new Obj2();
obj1.fun();
obj2.fun();

You scenario is not entirely clear but here are some options:-

 function globalFunc()
 {
     alert(this.__class__);
     //Note globalFunc now has access to much more.
 }

 function MyObject(){ }
 MyObject.prototype.test=function(){
   globalFunc.call(this);
 }
 MyObject.prototype.__class__=MyObject;

To add a closure for event handling

MyObject.prototype.test = function(){
   var self = this;
   var elem = //get some element;
   //Not cross-browser but for illustration
   elem.addEventListener('click', fnEvent);
   function fnEvent() { globalFunc.call(self); }
   elem = null
}

I don't understand well what you are trying to do, but here's an idea that could inspire you something.
The "constructor" property helped me well when I was trying to use JS as a OO language.

o.constructor will give you the myObject function reference.

But in my opinion, you should give functional programming a try instead of OO to get the most from Javascript

temp is the caller but it does not have the property __class__. You only defined that for test.

caller is non-standardised and really brittle; best avoided. Much better to pass the value explicitly:

MyObject.prototype.test= function() {
    element.addEventListener('click', function() {
        globalFunc(MyObject);
    });
};

or:

MyObject.prototype.test= function() {
    var myclass= arguments.callee.__class__;
    element.addEventListener('click', function() {
        globalFunc(myclass);
    });
};

Functions are not "owned" in JavaScript. Functions are first class objects in JavaScript, which means they can be passed around like any other variable and assigned as properties of many objects.

this inside a function body will give you a reference to the object on which the function was called, if called as a method (e.g. myObj.myMethod()) or via the Function prototype's call() or apply() methods (e.g. myFunc.call(myObj)). Inside a function called on its own (e.g. myFunc()), this will usually be the global object (the same as window in most browsers).

Short answer, there really is no way to do what you are trying to do. Javascript just doesn't work like that.

Long answer...

Almost every programmer I've met who has e to JavaScript from a language that uses a classical object model has tried to do what you are doing: emulate the classical OOP style they are used to with Javascript. There is no shame here, I did this, even the famous Douglas Crockford experimented with this, and then later gave it up. I did too. I still think it was a neccessary thing for me to try this stuff in order to really learn the langauage

Do not be fooled by the curly braces, and familiar looking operators. At it's core it has very little in mon with Java! JavaScript is a functional langauge: functions are objects in their own right.

Bluntly: There is no way to do what you are trying to do - have objects with private properties you can access through this

Saying that is easy :) Understanding how to apply that is more difficult

There are no classes, there are only objects. Objects only have properties. Properties of objects may have values. Those values may be functions. this is set when the function gets called, it could be anything

Closure is the only way to achieve true privacy in JavaScript. Everything else either leaks into some enclosing scope, relies on obfuscated property names, or can be circumvented in some way by the caller, or leaks memory even after your objects are no longer referenced (as there are no destructor function to do your clean-up in).

What you are doing is still a good thing to try and do, by attempting it you will bee a better JavaScript programmer by figuring out: why you can't do some of it more importantly why you probably shouldn't

发布评论

评论列表(0)

  1. 暂无评论