Get the name of the prototype object

This question has just been raised, so it can update the question with what I did

I solved it by iterating over a window object (or a user-specified root object), and when I found the correct instance, I canceled it and got the name from the index. The final solution can be found here.

https://github.com/AndersMalmgren/Knockout.BindingConventions

End of update

I plan to write a conditional agreement on creating the source code for the template for KnockoutJS / MVC. I started from the small client side of POC and immediately ran into a show stop.

My plan uses this syntax or something like that

MyApp.EditCustomersViewModel = function() { ko.templates.loadView(this); }; 

At the same time, it checks the tamplate cache or retrieves templates from the server using the name of the object as a key. The problem is that I cannot get the name of the prototype object, I tried this

 Object.prototype.getName = function() { var funcNameRegex = /function (.{1,})\(/; var results = (funcNameRegex).exec((this).constructor.toString()); return (results && results.length > 1) ? results[1] : ""; }; 

If it works for objects defined this way

 function MyClass() { } 

If you add a prototype to the above object, it will not work, or if you define it as follows

 MyApp = {}; MyApp.MyClass = function() { }; 

The prototype and scope are two points, so this is a show, any ideas?

Fiddle: http://jsfiddle.net/aRWLA/

edit: The background for this is as follows.

On the server, you have a structure like this

  • Templates \ [ViewName] \ index.html
  • Templates \ [ViewName] \ sub-model-template.html

on the client that you will do

 MyApp.EditCustomersViewModel = function() { ko.templates.loadView(this); }; 

which will generate an ajax request with the name of the object as a key that will retrieve all the templates for the view in question

+6
source share
4 answers

Only restored functions ( function someFunc() { ) have a restored name.

Assigned functions are not executed, because you do not name a technical function, but create an anonymous function and assign a reference to it (in memory) to a named variable.

So this is the name var, not the function that is called.

This makes you think about getting function names to a large extent without starting, since in any vaguely mature template you will write methods, not using hoisted functions - and, of course, functions are assigned.

Named expressions (see other answers) are a partial workaround, but they have other problems - not least the lack of support in older IEs.

(Sidenote: I had long expected browser developers to build around this so that the names of the assigned functions will be available, but AFAIK is no fun yet.)

+4
source

I think that the problem is incorrect replacement of the function prototype: if you replace the function prototype object, you must save the constructor element in the prototype:

 function Test1() { } Test1.prototype={ constructor: Test1 }; MyApp={}; MyApp.MyClass=function MyClass(){ }; MyApp.MyClass.prototype={ constructor: MyApp.MyClass }; 

Your example: http://jsfiddle.net/aRWLA/1/

Modified example: http://jsfiddle.net/aRWLA/2/

+2
source

You can use expressions with function names :

 MyApp.MyClass = function MyClass() { ... }; 

But keep in mind that (suprise) they do not work correctly in all versions of IE.

See: http://kangax.github.com/nfe/

+1
source

THIS DOES NOT ANSWER THE QUESTION

However, the code may be useful to other people, so I leave it here, just in case. I do not expect continuation, but please do not abuse it for downvoting. Thanks.


I do not know your use case, so I think you have a design problem. The problem you are describing should not happen in practice.

But tell me what you need for this to work. An easy way to do what you need would be something like this:

 function findNamed(obj, fn){ for(var p in obj) if(obj[p] === fn) return p; return false; } var m = {}; m.MyClass = function() {}; console.log(findNamed(m, m.MyClass)); 

Of course, a solution can be turned into a more suitable form of OOP, but this is just to give an idea.

To reproduce your use case, it will look like this:

 m.MyClass = function() { findNamed(this, arguments.callee); }; 

So the final code is:

 Object.prototype.getNameOfCall = function(fn) { for(var p in this) if(this[p] === fn) return p; throw "Callback not in object."; }; var m = {}; m.MyClass = function() { console.log(this.getNameOfCall(arguments.callee)); // MyClass }; m.MyClass(); // test it out 
+1
source

Source: https://habr.com/ru/post/923545/


All Articles