Append javascript functions and vars declaration to an object from a string - javascript

I'm facing the following problem:
I have a string which contains javascript vars and functions declarations.
Example:
// this is the content of the jsString var passed to the _MyClass ctor
var toto = "Hey";
var foo ="oh";
function myFunc(str) {
toto = str;
}
And I have a class declared like this:
class _MyClass
{
constructor(jsString) // where JsString is the above JS
{
this.aVar = 2;
}
}
And I would like to populate my _MyClass class with the JS string.
I need to be able to call:
var myClassInstance = new _MyClass(jsString);
myClassInstance.myFunc("test");
I know this is possible to populate the window object with the eval func, but I don't know if it's possible for an object (eval func on object is deprecated).
I also know that is not common, but it is used in a particular context where I haven't the choice.
Thank you in advance for your help.

The requirement is bizarre and I would strongly recommend that you do whatever you possibly can to get rid of the requirement in favor of passing data into your constructor, not a string containing code.
But for the requirement itself: Unless you know the names of the variables and functions in the string in advance, you cannot do this without a JavaScript parser (such as Esprima — that link is down right now, but I assume it's temporary).
Using Esprima or something like it, you'd:
Parse the code.
Use information from the parsing data (line and character, etc.) to modify the code string, changing var toto = ... to obj.toto = ... and function myFunc()... to obj.myFunc = function myFunc()... and such (being aware of and careful about losing the hoisting, since we're changing function declarations into function expressions). You'll also have to find and update references to the identifiers within the functions (which you can do with Esprima, and presumably with others).
Then in the constructor:
var obj = this;
eval(theUpdatedCode);
...to evaluate the code in the current context. That would assign the various things to obj.
Again, I would not do that, I'd do my best to change the requirement instead.

Related

Get a function name like printed in Chrome console

Considering this code :
var o = {};
o.f = function(){};
new o.f;
Chrome prints o.f {} into the console. Do you know how this o.f part is called? More importantly, is there any way to get this result without using the console? I'd like to extract the name of a method from the function itself, that is to say, without any additional information.
I already know how to get the name in this case :
function f(){}
f+'' // "function f(){}"
But it does not behave the same way in the situation described above.
The following content is mostly copied from comments.
I wanted to know if there is a "technical" word to talk about this o.f pattern, let's say for example "namespace", "identifier", or "function path". Then, I was wondering if there was a way to retrieve this information from a loaded script in a webpage. The following question may help you in understanding my goal, the paragraph which is right after the first code block is quite close to my idea : Does Chrome retain each object's constructor?.
Maybe I should have mentioned that my original goal was to generate a documentation at runtime :/ Something like a reflection API would have been helpful in this case. More precisely, I was looking for a way to include the name of a method into the decompilated form of the function. Look :
function Class(){}
Class.prototype.method = function(){};
Class.prototype.method + '' gives function(){}. I'd like to inject the method's name to get this result : function method(){}.
The problem is that I don't have any information about which function I'm currently serializing since the operation occurs when the user clicks a link. I know I could easily store the name somewhere, binding the data to the anchor element for example, that's obvious to me, I was just curious to know if there was a way to retrieve this data the same way as Chrome.
Well, this seems a simple enough question, as far as the naming of all these constructs goes:
o.f = function(){};
is a common statement, consisting of even more common expressions. o.f is simply one of 2 ways to access an objects' properties, commonly referred to as the dot-notation. Though I believe in JS the dot (.) isn't really seen as an operator, I'll be referring to it as the member-of operator henceforth.
Next we have the well-known assignment-operator, which assigns the right-hand operand to the left (member of the object o, called f).
The right-hand expression (needs to be evaluated to a singular value) is a function definition that, instead of a statement on its own, is used as an expression. Given that fact, we refer to this usage of functions as function expressions.
In this particular case, the function has no name, it's an anonymous function. Internally, most -if not all engines- will give it a name, but that's not something JS should know or indeed care about. As far as JS is concerned, this function has no name, and is only accessible through o.f. If you call this function like so: o.f(), its context will be that of the object o, effectively making this function behave as a method.
So basically your statement reads like this: "Assign, and create if required, to the member of o called f, an anonymous function." The function itself has no name.
Consider this:
var o = {f: function(){console.log('I am a function');}};
var foobar = o.f;
foobar();//logs I am a function
So saying the name of the function o.f is f doesn't always apply. Other variables or properties can reference the same function. That's because functions are first class objects, they can be returned, passed to and assigned to, from and by anything.
The answer, then, is to use either one of these 2 approaches:
You can change the function expression by adding a name, to turn it into a named function expression:
f.o = function newName(){};
The newName name is, apart from older versions of IE, not available outside of the functions' scope. This is required by the ECMA specifications see the details here. Anyway, now we can check for that:
var func = function func(){console.log(func);};
//same name:
func();//logs function func(){}
var foobar = func;
foobar();//logs function func(){}
func = 123;//<-- no longer function
foobar();//still function func(){}//func is still accessible
var hidden = (function()
{
return function named()
{
console.log(named);//access name
};
}());
hidden();//logs function named(){}
console.log(named);//undefined -> not visible outside the function itself
The name of the function is restricted to its own scope.
Use a regex, which is slightly hacky, and doesn't pick up on two variables/properties referencing the same function object:
o = {f: function(){console.log('I am a function');}};
for (var pName in o)
{//probably add o.hasOwnProperty(pName) check to be safe
if (o[pName] instanceof Function)
{
console.log(o.f.toString().replace(
/^function\s*\(/,
'function o.'+pName+'(')
);
}
}
This stringifies the function (giving function (){/*body*/}) and replaces function ( with function <propertyName>(. If the function already had a name of its own, that name is not replaced.
In general, this is not common practice in Javascript or in programming in general.
However, functions do have an attribute name - see Function.name.
but in your code o.f is a nameless function.
var o = {};
o.f = function(){}; //function (){} creates a nameless function.
you can define a name before the ()
var o = {};
o.f = function f(){}; //function f(){} creates a function with the name f
then
o.f.name == 'f'
NOTE: this functionality is NOT supported in IE, and is not a specification of EMCA
This is exposed as the name property of the function, and these day it is part of the standard (search for SetFunctionName in the spec). See also MDN, Chrome Platform Status, browser support. If you are asking specifically about the feature of auto-guessing the name from the variable name for anonymous functions, MDN calls that the inferred function name.
Back when the question was asked, the definitive discussion of this topic was kangax's article Named function expressions demystified (now a bit outdated).

Why is new being used with a function expression?

While looking at some source code I found this:
require["./helpers"] = new function() {...};
Why is new being used here? When I run this on JSLint I get
Weird construction. Delete 'new'.
So is this just a form of style, personal preference? Or is there something behind this?
It's a way of creating an object which allows this to be used during the creation.
This offers some direct reference to the object during instantiation that object literal syntax does not allow.
var o = new function() {
this.num = Math.random();
this.isLow = this.num < .5; // you couldn't reference num with literal syntax
};
The object literal version would need to look like this:
var o = {
num: Math.random()
};
o.isLow = o.num < .5;
So the anonymous function is basically used as a temporary constructor. We could just as easily use a named constructor function, but since we don't really care about the constructor, we just use a "disposable" one.
And of course since it's a function, it creates a local variable scope, so if you assign any functions to the new object, they will be able to close over local variables.
It's basically doing the same thing as an IIFE which returns a public interface (an object with public properties/methods which have access to the private scope of the function) of some sort, except for people who REALLY AND DESPERATELY want to use this during the construction, and can't be bothered to use call, bind or apply, or just flat out return a regular inline object.
Under the hood there are a few difference between IIFEs and constructor-functions when both are used in their anticipated ways... ...but in this instance, there really isn't anything inherently different about the final return value done either way, from a high-level (ie: as far as your program should be concerned).

use this.argu to store arguments a good practice?

i am new to front-end developing,and now i am reading a lot of js code written by other in my company and find they will use this syntax to store the arguments :
function func1(argu1,argu2){
this.argu1 = argu1;
this.argu2 = argu2;
// other code run here....
}
for me i usually skip this and use the argument directly in my code or get a variable for the n,like this:
function func2(argu1,argu2){
alert(argu1);
alert(argu2);
var arguOne = argu1,arguSec = argu2;
// other code run here...
}
so i want want to ask why use this syntax to store an arguments?
is this a good practice ?and why?
Have i ever miss some concepts that i should know?
see the fiddle, written by the my co-worker who has been no longer a front-ender....
In your first example, func1 can be used to create objects. It is effectively a class definition (constructor). It can be used as follows:
function func1(argu1,argu2)
{
this.argu1 = argu1;
this.argu2 = argu2;
}
var instance = new func1('a', 'b');
alert(instance.argu1);
alert(instance.argu2);
Lordy lord: Instead of defining the function, and calling it at the end, try using a closure. Just keep the function definition as is, but put it in brackets:
(function new_slider (arguments)
{
//your code here
})('#new_slider',1500,150,10);
This way, the function is declared, and invoked at the same time, all functions defined within the main new_slider function will have access to the arguments. There is absolutely no reason to use this.argu1 to store these values. If anything, it creates global variables, which is considered bad practice.
Please google closures in JavaScript, they're extremely powerful

How to retrieve the constructor's name in JavaScript?

Assume the following program:
var SomeConstructor = function() { };
var instance = = new SomeConstructor ();
The expression instance instanceof SomeConstructor yields True, so instance has to know somehow that it was constructed by the function SomeConstructor. Is there way to retrieve the name SomeConstructor directly from instance?
(In my problem at hand, I have a hierarchy of prototypes implementing possible signals in my application. I have to access the type of a signal which shall be equivalent to the constructor used to create that signal.)
On Chrome (7.0.544.0 dev), if I do:
function SomeConstructor() { }
var instance = new SomeConstructor();
console.log(instance.constructor.name);
it prints 'SomeConstructor'...but if SomeConstructor is defined as an unnamed function as you have it, it will print an empty string instead.
If I print instance.constructor it prints the same thing as it does if I print SomeConstructor in the code you have. The instanceof operator need only compare these two values to see that they are equal to be able to return true.
This code will get the name of the constructor, as long as it is not an anonymous function:
obj.constructor.toString().match(/function (\w*)/)[1];
Why would you need the class name? Let's say you want to save and restore class instances via JSON. You could store the class name in a "type" property, and then use a resolver function in JSON.parse to restore the objects. (See the sample code on this page).
So, in theory you could use the code above to make a generalized serializer that could handle any class instance, but parsing function strings is very inefficient. This overhead can be avoided by requiring all the classes you are going to store to provide the type explicitly:
function Foo() {}
Foo.prototype.type = 'Foo';
This seems silly and redundant, which is why I started on the quest to obtain the class name implicitly. But in the end I have to give in: there is no acceptable solution in JS :-(
No. You can use x.constructor to get a direct reference to C, but it's an anonymous function so there's no way of getting its name.
If it were defined like so:
function C() { };
x = new C();
Then it would be possible to use x.constructor.toString() and parse out the name of the function from the returned string. Some browsers would also support x.constructor.name[1].
[1] https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/name
You can also declare your class this:
var C = function C() { };
Now your C class constructor is a named function (no longer an anonymous function) meaning you can do:
x = new C();
console.log(x.constructor.name); // output: C
This code of yours that needs to know the constructor, can it access the constructor function itself? If so, you can just do that instanceof thing.
It seems that you need to know it by name. This sounds dangerous. Someone can create another constructor that happen to have the same name and it will pass (unless that's what you want, of course).
At least in React it might be
this.default.name

Is my javascript coding style following best-practice?

What is the 'best practise' with regard to coding style.
Should I use _ for private members?
Should I use this._privateMember?
Please re-write my code in proper style if its wrong:
(function()){
var _blah = 1;
someFunction = function() {
alert(_blah);
};
someOtherFunction = function {
someFunction();
}
}();
I would read this and incorporate any part you agree with:
http://javascript.crockford.com/code.html
You do not have to agree with all of it
I don't think there is one. Use a prefix if you think it helps.
I use _ for private members because it distinguishes them which can be quite helpful in Javascript when you have variables coming from all over the place. But they do clutter the code a bit.
I don't use _ for variables that are declared using var. I do however, use _ to denote object members that shouldn't be access directly.
Some people (who are strange in my opinion :P), also prefix variables with a $ if it contains a jQuery object.
As long as you are consistent with what you do, there are no problems.
Aside from just the code you're showing now, you should use Capital Letters to distinguish constructor functions, and camelCase to name instances of objects.
function Foo (val) {
this.set(val);
};
Foo.prototype.get = function () {
return this._dontTouchMePlease;
};
Foo.prototype.set = function(val) {
this._dontTouchMePlease = parseInt(val, 10);
};
var aFoo = new Foo(6);
I think that its generally accepted that if a variable name starts with a _, you probably shouldn't touch it (accept in dire cirumcstances and even then, two keys and special codes should be provided).
If I'm remembering my Crockford correctly, you'll want to put var in front of the two inner functions, otherwise they will be implicit globals. If you want them to be globals, then that's moot. Either way, your second inner function declaration should probably end in a semicolon. This might be a misformating thing, but I think its generally accepted that the bodies of functions are indented one more level in. Also, I've never seen the (function()){/* stuff */}(); construction before, but that says pretty much nothing.
I'd write it these ways - one for if your just declaring a function and another for if your using an anonymous function and immediately applying it to get a result, because I don't which one you're trying to do (again, if you want the inner functions to be global, then this won't be what you intended):
//function declaration
var myFunction = function () {
var _blah = 1;
var someFunction () {
alert(_blah); //or console.log(_blah); for debugging purposes
};
var someOtherFunction () {
someFunction();
};
};
//using a one-of to assign a result
/* NOTE: if you are using this version, myResult will be undefined
(at least given the functions you provided), but like I said,
I don't recognize the construction you provided, and am therefore
assuming that you meant one of these two, which could be a perfectly
falacious assumption, and in that case, my apologies
*/
var myResult = function () {
var _blah = 1;
var someFunction () {
alert(_blah);
};
var someOtherFunction () {
someFunction();
};
}();
BTW, (and I don't want to overstep) Crockford's "JavaScript: The Good Parts" is a stellar reference for JavaScript syntax. He also has, on his website a JavaScript style guide of sorts (though I don't know how widely followed it is). Link is: http://javascript.crockford.com/code.html
I also use the "_" in c# for private/protected members. It is a fast way to see if the variable is a member-variable or not. And you can access it faster with code-completion because you don't get in mess with the public members (private: _blah , public property: Blah).
But are there any private members in javascript anyway? I think every variable defined as member is accessible from the outside.
So you don't have a public wrapper for the private member. And that means the "_" is a bit a overhead and the same can be achieved with "this.".
I prefer you to use the following stuffs which is preferably used around the world programmers.. see below
i = Int
f = Float
o = Object
r = Return
a = Array
e = Element
g = Global declaration
hook = a function which can be used for hooking with other functions
call = a function which can be used for making call from client to server system
sync = a function which can be used for SYNC
and so on.. you can prefix on your coding...

Categories

Resources