How to access the function property of a javascript object using variable - javascript

Hi consider below code
let test={
a:function(){
console.log('Hi')
}
}
Is there a way to invoke property 'a' using a variable ?
This works ,
let test={
a:function(tmp){
console.log(tmp)
}
}
let functn='a';
test[functn]("hello");
but is there anyway to invoke the same like below code :
let test={
a:function(){
console.log('Hi')
}
}
let functn='a("hello")';
test.function;
The actual use case:
This is protractor system test related question,
I have a parent object with css locator [id=1] and the child elements has the locators [id=1]>div , [id=1]>span etc.
so currently parent element is stored as
let parent = element(by.css('[id=1']) ,
child as
let child1= element(by.css('[div]')
So to find all child elements of the parent element the function is :
element(by.css('[id=1']).element(by.css('[div]')
so instead of writing the locator again, i want to achieve:
parent.child1

This works ,
Yes, it does. Do that.
but is there anyway to invoke the same like below code :
No.
let functn=a("hello"); calls the function in the variable a and assigns its return value to functn.
Assuming that doesn't fail (because a isn't declared), then test.function looks at the value of the property named function (which has nothing to do with the variable function you just declared) on the object stored in test and does nothing with it.

Was able to make it work, i am converting everything to string and calling it using eval function:
let test={
a:function(tmp){
document.write(tmp)
}
}
let functn='a("hello")';
eval(Object.keys({test})[0]+'.'+functn)

If in case you are looking for a currying solution:
let test={
a:function(str){
return () => console.log(str)
}
}
let functn=test.a("hello");
functn();

At first you are passing a string which is not neccessary if you dont accept any parameters.
What you can do is using getters.
Documentation: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Functions/get
let test={
get a (){
console.log('Hi')
}
}
So every time you are trying to access a it will be executed and so will print you 'Hi' in your console.
test.a;

There is and simpler form of the code
// Using Function Arrow
let test = (message => 'Hello World!')()
console.log(test)
// Using factory function
let data = function() {
return {
nome:'Jack'
}
}
console.log(data())
console.log(Object.values(data()))

You could change your approach to one without using eval by taking an array of key and parameter and a function which take the key and parameter and calls the function of the object.
let call = ([key, parameter]) => test[key](parameter),
test = {
a: function(tmp) { console.log(tmp); }
},
parameters = ['a', 'hello'];
call(parameters);

Related

Is it possible to identify a role after building a Vuejs project?

I have a file that exports some functions in a Vuejs project, and I need to use them also in an external environment .. inComponent I know which function I should use by identifying by name and comparing with a .JSON file this works cool in the environment of development but when I build the project the functions are renamed as in the image:
Is there any other reference in these functions where I can identify them other than by name? any reference in memory I don't know? Thank you!
You can define a unique value in the body of each function and then when you have a reference to one of the functions in your list you can call the toString() method of the function reference to get the source code of the function - and then check whether the desired unique value is present in the code.
Something like this:
const myFunc1 = function (...)
{
const uniqueIdent = 'zvjbesvfexrxe3cg4g3ewumkaj2hrz9m';
.....
}
const myFunc2 = function (...)
{
const uniqueIdent = 'y4wxfjedrr3mh6k5ju2gcff6wxafjcz5';
.....
}
// make the list of functions globally available
window.myFuncList = { myFunc1, myFunc2 };
// try to find the uglyfied name of Func2
var key;
var realNameFunc2;
for (key in window.myFuncList)
{
if (window.myFuncList[key].toString().indexOf('y4wxfjedrr3mh6k5ju2gcff6wxafjcz5') !== -1)
{
realNameFunc2 = key;
break;
}
}
// you can now invoke your function as realNameFunc2(...)

Is is possible javascript function to return new DOM element but created with jQuery

Example:
function getNewElement(elementName, elementClass) {
return $('<p>')
.addClass(elementClass)
.text(elementName);
}
And then i can reuse it like:
const paragraph = getNewElement('test', 'some-class');
const paragraphSecond = getNewElement('test2', 'some-class2');
Is there any way to run the code or any similar approach ? Thanks
The 0th item in a jQuery object is the native DOM Element object. As such just add [0] to the return statement in your function to get your desired output:
function getNewElement(elementName, elementClass) {
return $('<p>').addClass(elementClass).text(elementName)[0];
}
const paragraph = getNewElement('test', 'some-class');
console.dir(paragraph);
const paragraphSecond = getNewElement('test2', 'some-class2');
console.dir(paragraphSecond);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
That being said, there's nothing inherently wrong with returning a jQuery object from the function which will stop it from being re-used. Any problem would only come from how you use the result of the function in later logic.
you could create the element using the following approach:
function getNewElement(elementName, elementClass) {
return $(document.createElement("p"))
.addClass(elementClass)
.text(elementName)
.get(0);
}
The function below generates a tag and returns it:
function getNewElement(elementName, elementClass, tagName = "p") {
return $('<'+tagName+'>').addClass(elementClass).text(elementName)[0];
}

Javascript Revealing Module Pattern in AngularJS Service not working

I'm using the following code in my angularJS service to get some task done :
angular.factory('promiseFactory', function(){
var artistIds = [];
function setArtistIds(artistIds){
artistIds = artistIds;
}
return {
createPromiseForNotification: promiseFactory,
getNotis: getNotis,
setNotis : setNotis,
//setArtistIds : setArtistIds,
artistIds : artistIds
}
});
This factory is used in another factory notifications.js wherein I'm trying to set
promiseFactory.artistIds = [1,2,3];
on some ajax call but its not working, when I use the artistIds variable in any of the functions of my promiseFactory, it turns out to be blank array [] (the initial value). Why?
Ok, Secondly, this thing works when I use a function called setArtistIds to implement the same thing but even then I have to do something like
function setArtistIds(i){ // Right
artistIds = i;
}
But not when I do it like this :
function setArtistIds(artistIds){ // Wrong
artistIds = artistIds;
}
Can someone please explain me what wrong I'm doing.
When you are executing this line of code:
promiseFactory.artistIds = [1,2,3];
You are only changing property of the object returned by your factory.
But all your methods not even using it, they are using variable artistIds in the closure.
In order to fix this error, add getter and setter to your factory.
When you are naming parameter of the setter function the same way as your closure variable, you are hiding it. That's why it was not working.
Just give it another name.
angular.factory('promiseFactory', function(){
var artistIds = [];
function setArtistIds(newArtistIds){
artistIds = newArtistIds;
}
function getArtistIds(){
return artistIds;
}
return {
createPromiseForNotification: promiseFactory,
getNotis: getNotis,
setNotis : setNotis,
setArtistIds : setArtistIds,
getArtistIds : getArtistIds,
}
});

passing an object to a function in javascript

This might seem like a noob question but I'm not sure what to do. I have function with 2 variables.
function someInfo(myVar1,myVar2)
{
this.lmyVar1=myVar1;
this.myVar2=myVar2;
}
myInstance=new someInfo("string1","string2");
function drawVariables(){
document.write(myInstance.myVar1);
document.write(myInstance.myVar2);
}
I want to use the same drawVariable() for multiple instances. I just can't figure out how the exact syntax for that. How can I make drawVariable() use a different instance of someInfo without repeating anything? Is there a simple example or tutorial I can follow?
Add an argument to the definition of function drawVariables. In the code below, this argument is called info. Now you can use info as your object inside the drawVariables function, and while calling drawVariables function, you can pass whatever instance you want to pass it. drawVariables function would now work with whatever instance you pass it while calling.
function someInfo(myVar1,myVar2)
{
this.myVar1=myVar1;
this.myVar2=myVar2;
}
// Create two separate instances
myInstance=new someInfo("string1", "string1");
myInstance2 = new someInfo("string2", "string2");
// info is the argument that represents the instance passed to this function
function drawVariables(info){
alert(info.myVar1 + ", " + info.myVar2);
}
// Call the function twice with different instances
drawVariables(myInstance);
drawVariables(myInstance2);
See http://jsfiddle.net/WLHuL/ for a demo.
function drawVariables(instance){
document.write(instance.myVar1);
document.write(instance.myVar2);
}
Would it make sense for you to do it this way?
function someInfo(myVar1, myVar2)
{
this.lmyVar1 = myVar1;
this.myVar2 = myVar2;
this.drawVariables = function ()
{
document.write(this.lmyVar1);
document.write(this.myVar2);
}
}
function Test()
{
var obj1 = new someInfo("aaa", "bbb");
var obj2 = new someInfo("xxx", "zzz");
obj1.drawVariables();
obj2.drawVariables();
}

javascript: dynamic call of nested function

in an existing implementation (can't change the structure much), i'm trying to call a function which is nested inside another function:
function outer(innerFunction, obj) {
//TODO: call innerFunction here, passing obj as first parameter
function inner1(obj) {
alert(obj.key);
}
}
outer('inner1', {key:'value'});
jsfiddle is here: http://jsfiddle.net/tbyyw/
i've alreay thought about using eval(), but i don't know how to pass an object - and they say 'eval is evil' ;)
another solution i've come up with is checking the innerFunction string, but this means i have to know which inner functions exist (besides, adding new functions would mean having to write extra checks then):
if(innerFunction == 'inner1') inner1(obj);
so is there another way without changing the overall implementation?
Without changing the overall structure eval appears to be the only option:
function outer(funcName, obj) {
var func = eval(funcName);
func(obj);
function inner1(obj) {
alert(obj.key);
}
}
There's nothing particularly "evil" about eval as long as you have full control over the code, but if you want, you can insert an additional security check:
if (funcName.match(/\W/))
throw "invalid function name!";
var func = eval(funcName);
This will raise an exception if someone tries to pass anything else than a simple identifier, i.e. a function name.
Is this what you wanted?
function outer(innerFunction, obj) {
var fn = {
inner1: function (obj) {
alert(obj.key);
}
};
fn[innerFunction](obj);
}
outer('inner1', {key:'value'});
http://jsfiddle.net/tbyyw/1/
A simple switch statement would be least intrusive. Or is the function name completely dynamic?
function outer(innerFunction, obj) {
switch (innerFunction) {
case "inner1": inner1(obj); break;
}
function inner1(obj) {
alert(obj.key);
}
}
outer('inner1', {key:'value'});
​

Categories