-2

javascript gurus! I realize the title to this question might be a little confusing. But I don't quite know how to explain it.

So let me just give an example:

function foo(txt){
    return "Hello " + txt);
}
function bar(txt){
    if(/* bar is called as an argument */) return txt;
    if(/* bar is called normally */) return "Bar";
}

foo(bar("world!"));   //Returns "Hello World";
bar("world!");        //Returns "Bar";

I want bar() to do something differently if it's called as an argument for another function than as if it were called on it's own.

I can't seem to find any way for bar() to know if it's an argument in another function or not because it seems that when the browser runs foo(bar("world!")); it runs bar("world!") first and then gives foo() whatever was the result of bar().

I thought i could check the call stack for bar() because I figured that foo() was calling it. but it's being called by the same function that called foo() before foo() ever gets called.

I'm starting to feel like this just isn't possible.

EDIT: so obviously most people are a little confused as to why i would want to do this.

I'm making myself a function for quickly building HTML elements. I can call the function and just pass in the parent element i want them to attach to and a bunch of tag names and it creates those tags and appends them to that parent element

obj = c(tableElement,"td","td","td")

this will create 3 cells and append them to my table. but will not return anything. so that:

obj = undefined

but that's ok becuase if I change the original code to this:

obj = c(tableElement,"td","td",true,"td")

then it will do the same thing. but instead pass the second cell to obj so that i can easily use that cell again later.

it comes in handy when i want to use Javascript to build a bunch of stuff that most of it I don't need to manipulate afterwards.

it all works good until I started adding the ability to nest elements. EX:

obj = c(tableElement,"tr",c("td",true,"td",true,"td",true),"tr",true)

this works well actually outputs:

<table>
   <tr>
       <td></td>
       <td></td>
       <td></td>
   </tr>
   <tr></tr>
</table>

and obj = the second row element only.

Now the trick that I'm trying to accomplish with all that is. I don't want to need the TRUE arguments in my nested c() function. they aren't necessary because they are required no matter what. If I had some way of knowing it was nested. then I could just ignore the TRUE arguments and my code would be that much more concise.

I'd also like to be able to have one of those nested cells be able to be returned to the obj variable as well.

I'm thinking my only option is to create a second function that works just a little bit differently for being used as an embedded element creator.

tyler mackenzie
  • 622
  • 7
  • 18
  • 2
    But you're not passing a function as an argument, you're calling the function and passing the string that is returned as the argument, that's what adding the parenthesis do, to pass the function as an argument you would have to do `foo(bar);` – adeneo Dec 02 '14 at 23:48
  • 1
    I have no idea why you would want to do this. – soktinpk Dec 02 '14 at 23:50
  • 1
    I think I get it now, and no, you can't do that, the function `bar` has no idea it's being called in any way related to the function `foo` the way you're doing it. – adeneo Dec 02 '14 at 23:52
  • _Why_ would you want to do that? – Etheryte Dec 02 '14 at 23:55
  • 2
    Why does it matter? Sounds like an XY Problem. What's the actual end you're working toward? –  Dec 02 '14 at 23:55
  • If you really need to pass a function and check against check http://stackoverflow.com/questions/5999998/how-can-i-check-if-a-javascript-variable-is-function-type – loshad vtapkah Dec 02 '14 at 23:59
  • does my edit make any more sense? or at least give a reasonable explanation of what I'm trying to do? I'm starting to realize there are probably several other ways I can achieve the same results without having to do something that's not possible. – tyler mackenzie Dec 03 '14 at 00:50
  • In case you didn't notice the updated response. Well I understand your problem, but the way you are trying to solve you doesn't make much sense. I can tell you straight away that this solution you are trying to introduce won't scale up in any sensible way. Creating HTML document from JavaScript is generally a bad idea. Please consider using http://handlebarsjs.com/ and save yourself a lot of time. – Konrad Szałwiński Dec 04 '14 at 21:02

2 Answers2

1

What you are asking for doesn't make much sense. The key principle behind functional programming is that the execution of the function is based only on the parameters that are provided during the function execution. If you would like to differentiate between this two functions you need to provide an additional parameter informing you the function what part of it should be called. In your situation I will imagine something like this:

function foo(txt){
    return "Hello " + txt);
}

function bar(argument,txt){
    if(argument) return txt;
    else return "Bar";
}

foo(bar(true,"world!"));   //Returns "Hello World";
bar(false,"world!");        //Returns "Bar";

I think that might solve the problem in your particular situation.

UPDATE:

Well I understand your problem, but they way you are trying to solve you doesn't make much sense. I can tell you straight away that this solution you are trying to introduce won't scale up in any sensible way. Creating HTML document from JavaScript is generally a bad idea. Please consider using http://handlebarsjs.com/ and save yourself a lot of time.

0

To figure out the context of a function call, you can use Function.caller (which is to supersede arguments.caller).

function bar () {
    console.log(bar.caller);
}

However, since both of your function calls are made from the same level of code, they will return identical results (or null if the invocation was from top-level code).
Therefore what you want is not possible. Also, why are you trying to do this?

Etheryte
  • 24,589
  • 11
  • 71
  • 116