So I was wondering if there is a way to use function.name but for objects.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
What I mean by this is to have something like this:
function myFunction() {}
console.log(myFunction.name); // logs "myFunction"
// but like
var myObj = {};
console.log(myObj.name); // logs "myObj"
and if it is possible, how would it handle something like this?
var myObj = {};
var myObj2 = {};
console.log(myObj2.name); // logs "myObj" or "myObj2" or both?
Two things
Object don't have name property by default, unless you specify the same while defining the object,
for example
var myObj = {
name : "myObj"
};
In myObj2.name, myObj2 is not the name of the object, it is the name of reference (variable) to object.
Short answer? No.
On the other hand, as you may know, global variables are part of window variable. Therefore, you could do something like:
function findName(obj, scope){
if(scope === void 0){
scope = window
}
for (prop in scope) {
if(scope.hasOwnProperty(prop) && scope[prop] == obj){
return prop
}
}
}
NOTE: This is extremly inefficent way to get variable name!
Related
var myObj = {
key: "element",
key2: "element2"
}
function stuff(obj) {
var a = obj;
console.log(a);
}
stuff(myObj);
How do I make stuff(myObj) console.log myObj, which is the name of the object? If I were to run this code, it would print that the argument myObj passed into stuff is an object and console.log its keys and elements. I want var a to store and console.log the name of the object instead of its contents, which in this case, is myObj.
You can't. JavaScript passes by value, there is no connection to the variable that was used to pass the object.
Take this example:
var foo = {};
var bar = foo;
window.baz = bar;
stuff(foo);
function stuff(obj) {
var a = obj;
console.log(a);
}
You now have 5 variables / properties which are all "names" for the same object.
If you need an object to have some kind of identifying name, then give it as a property.
var foo = { name: "foo" };
Use for-in loop to iterate through object. a and b are keys of the object which are mapped to id of the elements..
Try this:
var obj = {
a: "A",
b: "B"
};
for (var i in obj) {
$('#' + i).hide();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="a">A</div>
<div id="b">B</div>
<div id="c">C</div>
<div id="d">D</div>
It is possible! You can do something like this:
function stuff(obj) {
var a = Object.keys(window);
a.forEach(function(item, i, a) {
if (window[item] == obj)
{
console.log((item);
}
});
}
There is no (good) way to do that. The myObj variable has a pointer to the object in the memory. When you send myObj as parameter to a function, it will be sent by reference, so the obj parameter of your function will also have the pointer to the object in memory.
At this point the global variable myObj and local variable obj are synonyms for the same object. Modifying the property of one will also affect the other variable.
Theoretically there could be hundreds of variables pointing to the same object, but the object would never have any link back to any of the variables that point to it, so there is no way to retrieve the name of an object. There is no correct or original variable: all variables are identical no matter in what order they were linked to this object.
This said, of course if myObj is a global variable, it would be possible to compare your variable with all properties of the window object and then know which variable it was originally, but that's an awful waste of processing power. And it will only work with global variables.
So this should do the trick for global variable, but I strongly advise against doing this (most of all if it's a big project with lots of global variables). Still, if used during coding for debugging only, which I assume this is all about, it might be of some help:
function getVariableName(x) {
for (var i in window) {
if (window[i] === x) return i;
}
return false;
}
Attention: if you got more than one global variable pointing to this object, there is no way to know which of those variable names you will get back ... javascript does not define a fix order of enumerating properties of an object. The first match will be reported back!
I have a variable at some point of a JavaScript code. Now I would like to get the name of the function (aka scope) where that variable was declared. So for example if that variable is a field of an oject, I would like to get the name of the object's type.
Consider the following code:
function MyClass() {
this.name = "MyName";
this.age = 20;
}
var myVariable = new window.MyClass();
alert(getDeclaringScope(myVariable)) // should alert 'window'
alert(getDeclaringScope(myVariable.name)) // should alert 'MyClass
Is there any way to implement the getDeclaringScope function?
UPDATE
I wanted to use some technic like this to access to access a kind of "static" variable where meta information is stored for knockoutjs observable. A farly simplified example:
var META = {};
META["MyClass"] = {};
META["MyClass"]["MyArray"] = { ElementType: "MyOtherClass" };
function MyClass() {
this.MyArray = ko.observableArray();
}
function MyOtherClass() {
this.name = "a";
}
ko.observableArray.fn.addFromPlainObjects = function(plainItems) {
var elemType = .... here I wanted to get "MyOtherClass" from the META global variable
// create MyOtherClass and map the plain items to it... etc.
}
No.
The object has a reference to its constructor, but the constructor could be referenced from many objects, not just window in this case. It could be accessed directly with a variable (as opposed to a property):
var MyClass = window.MyClass;
var foo = new MyClass();
You can create a back-reference explicitly in your object model, as constructor functions are objects.
window.MyClass.backref = window;
Though this is most likely not what you want. I suspect you have a misunderstanding regarding what the scope of a variable is; a variable scope has nothing to do with object properties. As such, there is no notion of "declaring scope" that represents the object and object property from which a variable reference was retrieved, as you seem to conceptualize it.
You can use instanceof and constructor:
Eg.
myVariable instanceof MyClass; //true
myVariable.constructor;
// returns
function MyClass() {
this.name = "MyName";
this.age = 20;
}
Check: instanceof and constructor
Let's say I have an object:
obj = {func1: function(){return $(h1)};} // notice, there is no $ defined anywhere...
And somewhere else I have a line
jq = require('jQuery');
Now want to write a function or something, that takes object and a jQuery as an argument and binds it so that I can do something like this:
obj2 = myBind(obj, jq);
obj2.func1(); // works
obj = {func1: function(){return $(h1)};}
notice, there is no $ defined anywhere...
Then it's going to stay undefined, unless you create such a variable in any parent scope (like the global one).
You however cannot inject variables into scopes you don't "own", you cannot access the scope of the obj.func1 closure from the function reference - you need to put your code in that scope beforehand.
You might however use properties instead of variables, something like
var obj = {
func1: function() {
return this.$("h1");
}
};
// later:
obj.$ = require("jQuery");
obj.func1();
What #bergi said is correct. A different solution might also be to use Function.bind in one way or another:
var obj = {
func1: function() {
return this("h1");
}
};
obj.func1 = obj.func1.bind(require('jQuery'));
// later:
obj.func1();
In JavaScript I want to make a function which takes an argument and in this function a variable will be created whose name will be the value of the argument.
For example if user pass "jack" in the argument then in function I want a variable whose name is jack like:
var jack = "";
Typically, you won't need to do this. As Bergi pointed out, a local variable would usually suffice. However, in the event that you do need to use this technique, you could give the property to the window object:
function setVariable(userPassedString);
window[userPassedString] = "";
}
Don't use eval for this, ever, no matter how tempted you are to.
Creating local variables via a function is typically a bad idea. You could accomplish something similar by passing a local object around, e.g.
function setVar(o, name, value)
{
o[name] = value;
}
Then, inside your local scope:
var o = {};
setVar(o, 'jack', 123);
// o.jack contains 123
In this way, if the need would really arise (this is rarely required) to introduce global variables in this manner, you can always call the function like this:
setVar(window, 'jack', 123);
// now window.jack == jack == 123
The best that you can do about is to create an object and assigns the variable name to the keys of the created object like this -
var myvar={};
function create(var){
myvar[var]='values';
}
You could always use a dictionary. Here is a very simple stub:
function Dictionary(){
var container = {};
this.set = function(key, value){
container[key] = value;
}
this.get = function(key){
return container[key];
}
}
var vars = new Dictionary();
vars.set('foo', 'foo rocks');
vars.set('bar', 'bar rocks too');
console.log(vars.get('foo'));
console.log(vars.get('bar'));
To prevent using the window global array, you can create a local array which holds your variables.
function doSomething(var) {
var vars = {};
vars[var] = value;
}
I have a global variable MyGlobalVar and some code that looks like this:
var MyGlobalVar = null;
function PlayWithMyGlobal() {
MyGlobalVar = new Object();
.... adding properties to MyGlobalVar
MoreFun(MyGlobal);
}
function MoreFun(TheVar) {
is TheVar here a local or just a reference to the global?
}
If I pass the global variable, am I still working with the global?
Thanks.
If I pass the global variable, am I still working with the global?
Thanks.
It depends whether variable you pass is an object or a primitive (number, string, boolean, undefined, null are primitives) value in the first place. Objects are passed by reference and primitives by value.
In your case, you are passing object:
MyGlobalVar = new Object();
And in JS, objects are passed by reference. So you are still working on that variable.
You can confirm it like this:
var MyGlobalVar = null;
function PlayWithMyGlobal() {
MyGlobalVar = new Object();
MoreFun(MyGlobalVar);
}
function MoreFun(TheVar) {
MyGlobalVar.foo = 'I am foo'; // property created here
}
PlayWithMyGlobal();
console.log(MyGlobalVar.foo); // I am foo
If the global variable is an object, then you're still working with the global variable. Otherwise, it's a copy.
As shown and annotated below, your variables point to the same global object.
var MyGlobalVar = null;
function PlayWithMyGlobal() {
MyGlobalVar = new Object(); // <--- Object
MoreFun(MyGlobalVar); // <--- Passing object reference
}
function MoreFun(TheVar) {
TheVar.test = 'Did I modify global?';
alert(TheVar === MyGlobalVar); // true
alert(MyGlobalVar.test); // "Did I modify global?"
}
Yes, you have a local reference to the same object that is referenced globally.
A simple test would be...
console.log(MyGlobalVar === TheVar); // should be true