If one of my functions get an undefined parameter passed, I want to get the name of the variable outside the function so I can better troubleshoot the undefined variables. I.e.:
var myVar = document.getElementById("myTable").dataset.tablename;
//myVar: undefined
testVar(myVar);
testVar(param1) {
if (!param1) console.log(passed parameter ??? undefined);
}
//??? shall be "myVar"
I don't think the thing you want to achieve is possible. You can look at the stack trace at debug time, but I will give you further information and ideas here:
You could have a development policy in your team to name outside variables the same way as the parameters are at functions whenever possible. If you do so, this post will become useful.
You might introduce a policy to pass objects to functions, like {name: 'John', age: 3} and then you will know the keys.
You could create a Trackable prototype which would have a key and a value, like this:
function Trackable(name, value) {
this.name = name;
this.value = value;
}
and pass trackables to functions when their names will be needed, thus you will call testVar(new Trackable('myVar', myVar)) and inside you will check param1.value against undefined and if it is undefined, then use the name in your report.
Related
I'm having trouble figuring out how to customize console.log() so that it automatically prints out the label for each argument I pass into it. For example, I often do something like this, so that it's clear what each log is printing out:
console.log('firstName: ', firstName);
I would love to be able to simplify this to:
my.log(firstName);
Is there any way to pass the variable names of the caller args into console.log()? Or is there another way to do this? My wish is that I don't have to type out the variable name twice, just the once. And ideally print out multiple arguments each with its own label on its own line in the console. I'm aware that I can access the arguments list, but I don't know how to un-eval() each argument to get just its variable name, if that makes sense. I'm hoping it's something super-easy I missed.
Doing it the way you want is impossible (the log function doesn't know what name you called things.)
The way I work around this is to use the object shorthand {firstName}to create a temporary object.
You can then either use .log or .table to display it:
const firstName = 'bob';
console.log({firstName});
console.table({firstName});
// It also works for multiple variables:
const lastName = 'smith';
console.log({firstName, lastName});
You could use console.table() to print things in a more readable form:
(Look in the real console to see it.)
var obj = {
firstName: "name",
lastName: "smith"
};
function log(obj) {
console.table(obj);
}
log(obj);
Try this :
var my = {
log : function(name) {
console.log('firstName: ', name);
}
};
my.log("Rohit");
Suposse an function:
function get(){}
this will get an variable
var name = "Eduardo";
get(name);
function get(n) {}
And i want to show the name of the variable that was passed, without know this name.
function get(n) {
return getNameVariableFromValue(n); // Pseudocode for explain my question
}
so, i want the name of variable without previouslu knowing this name.
PD: My question is mainly to know, who is a variable in the window object, without know this name or value
Your question assumes that no two properties would ever have the same value, which is highly unlikely. But, making that wild assumption, you'd need to make the new window property explicitly rather than just declare a global variable and then you could use Object.keys() to enumerate all the key names of the window object, looking for the one that matches your value. When found, report the key name.
window.myGlobal = "Test";
Object.keys(window).forEach(function(key){
if(window[key] === "Test"){
console.log(key);
}
});
This code won't work in the Stack Overflow snippet environment due to sandboxing, but you can see it working here (make sure to have your developer's tools console open when running).
You can send the value as an object to the function and do something like below
function get(n) {
return Object.keys(n)[0];
}
var name ="Test1";
var name2 = "Test2"
console.log(get({name}))
console.log(get({name2}))
Could anyone explain why this code returns
""
in firebug console?
Don't down-vote thinking it's just a typo! :O
I was curious to know why it doesn't throw an error!!!
function mds() {
var {
namex,
score,
className
}
= {
namex: 'NAME',
score: '10',
className: 'Oop'
};
this.test = function () {
return name;
};
}
var x = new mds();
x.test()
I would also love to hear more details on this type of variable mapping (or a link) ?
UPDATE:
I would like to know why name is predefined with value "" in console?
The JavaScript part of the explanation here is simple.
When you do this:
this.test = function () {
return name;
};
It will first look for a variable named name in the scope of the function this.test(). When name is not found there, it will check in the parent function's scope as well. And since name is not defined there as well, it will look in the global scope, which is window, and returns the value of window.name, which in this case is an empty string. This (window.name) is what you are seeing when you run name in the console (or Firebug). This much is simple.
The value of window.name is decided according to it's definition in the HTML Standard (not according to ECMAScript rules). This MDN page says:
window.name - Gets/sets the name of the window.
And in your case, the name of the window is empty, hence the empty string you are getting. That's the simpler explanation of why window.name is empty.
If you really want to understand why window.name is empty here, you need to check out the HTML Specification for what it says about browsing contexts. It says that the value of window.name will be the name of the current browsing context.
A browsing context is an environment in which Document objects are presented to the user. (from the spec)
For example, when you create a link in HTML using the below code, the target attribute specifies the target browsing context in which the page is to be opened.
Click me
See more examples in this JSBin.
Hope this was somewhat helpful. Read the HTML Spec to understand more about browsing contexts.
Even if you run the below code you get "".
function ha() {
return name;
}
ha();
returning of "" has no way related to
var {
namex,
score,
className
}
= {
namex: 'NAME',
score: '10',
className: 'Oop'
};
Another way to test it is, Just type 'name' press enter in console.
""
Updating as per "Krishna" observation.
Looks like name is predefined in console context. So if the user doesnt have another declaration of name within the scope the console returns an empty string "". If user has declared name="xyz" then xyz is returned
name is a legitimate window property.
Windows can have names. And they can be useful.
As in:
Open a new window, with the name of namedWindow!
...and to make this more informal, we should add that: a link with a named target will either open in an existing window with that name or will create a new one with the given name in case it's not.
And because the "name" token is a global property of the window context; stating: name in the console or anywhere in the script will of course return an empty value (of a proper/accepted type), that is: a string. In this case [meaning the window.name hasn't been defined yet] an empty ("") string, is the only correct value for that property.
Whereas an unset event of a window, or any DOM element - if it exists - should return null, not undefined or god forbid an empty string, because they (event properties) expect functions; and functions are of type object, and null represents an empty object.
However, an unset, inline event attribute of an html element - should return an empty string ("").
Try this,
var {
namex: name,
score: score,
className
} = {
namex: 'NAME',
score: '10',
className: 'Oop'
};
actually object have to be key value pair
In ColdFusion, if you want to reference
<cfargument name="x">
then you say:
arguments.x
In JavaScript, if you have a function:
var myFunction = function(x) {
then, is there a way to explicitly reference the arguments scope like maybe:
arguments[0].x
or something so that you're scoping everything.
There is no way to achieve the same functionality by using the arguments variable, as it holds no information on parameter names. To circumvent this, you could switch from using multiple parameters to one compound parameter object that holds actual parameter values in its members.
<script>
function abc(params) {
var x = params.x;
var y = params["y"];
}
abc( { x: 10, y: "hello" });
</script>
This way however you lose some of the readability of the code at the function signature, plus you must provide param names on the calling side.
You can reference the arguments pseudo-variable, but the arguments are indexed by number, not by name. It's a good idea to avoid messing with arguments directly; a common idiom is to convert it to a real array:
var args = Array.slice.call(arguments, 0);
I'm afraid not. You can explicitly use x or arguments[0] but nothing more. Unless, as pointed out from others, you pass an object.
I'm working with XULRunner and came across the following pattern in a code sample:
var StrangeSample = {
backingStore : "",
get foo() { return this.backingStore + " "; },
set foo(val) { this.backingStore = val; },
func: function(someParam) { return this.foo + someParam; }
};
StrangeSample.foo = "rabbit";
alert(StrangeSample.func("bear"));
This results in "rabbit bear" being alerted.
I've never seen this get/set pattern used in Javascript before. It works, but I can't find any documentation/reference for it. Is this something peculiar to XUL, a recent language feature, or just something I missed? I'm puzzled because I was specifically looking for something like this a few months ago and couldn't find anything.
For reference, removing "get" or "set" results in a syntax error. Renaming them to anything else is a syntax error. They really do seem to be keywords.
Can anyone shed some light on this for me, or point me towards a reference?
As suggested by Martinho, here are some links explaining the getter/setters in JS 1.5:
http://ejohn.org/blog/javascript-getters-and-setters/
http://ajaxian.com/archives/getters-and-setters-in-javascript
Be aware though, they don't seem to be supported in IE, and some developers have (legitimate) concerns about the idea of variable assignment having side-effects.
get/set are not reserved keywords as Daniel points out. I had no problem creating a top-level functions called "get" and "set" and using the alongside the code-sample posted above. So I assume that the parser is smart enough to allow this. In fact, even the following seems to be legitimate (if confusing):
var Sample = {
bs : "",
get get() { return this.bs; },
set get(val) { this.bs = val; }
}
According to Mozilla, they are not in ECMAScript.
JavaScript Setters And Getters:
Usually the setter and getter methods follow the following syntax in JavaScript objects. An object is created with multiple properties. The setter method has one argument, while the getter method has no arguments. Both are functions.
For a given property that is already created within the object, the set method is typically an if/else statement that validates the input for any time that property is directly accessed and assigned later on via code, a.k.a. "set". This is often done by using an if (typeof [arg] === 'certain type of value, such as: number, string, or boolean') statement, then the code block usually assigns the this.(specific)property-name to the argument. (Occasionally with a message logging to the console.) But it doesn't need to return anything; it simply is setting the this.specific-property to evaluate to the argument. The else statement, however, almost always has a (error) message log to the console that prompts the user to enter a different value for the property's key-value that meets the if condition.
The getter method is the opposite, basically. It sets up a function, without any arguments, to "get", i.e. return a(nother) value/property when you call the specific-property that you just set. It "gets" you something different than what you would normally get in response to calling that object property.
The value of setters and getters can be easily seen for property key-values that you don't want to be able to be directly modified, unless certain conditions are met. For properties of this type, use the underscore to proceed the property name, and use a getter to allow you to be able to call the property without the underscore. Then use a setter to define the conditions by which the property's key-value can be accessed and assigned, a.k.a. "set". For example, I will include two basic setters and getters for this object's properties. Note: I use a constant variable because objects remain mutable (after creation).
const person = {
_name: 'Sean';
_age: 27;
set age(ageIn) {
if (typeof ageIn === 'number') {
this._age = ageIn;
}
else {
console.log(`${ageIn} is invalid for the age's key-value. Change ${ageIn} to/into a Number.`);
return 'Invalid Input.';
}
},
get age() {
return this._age;
},
set name(nameIn) {
if (typeof nameIn === 'string') {
this._name = nameIn;
} else {
console.log(`Change ${nameIn} to/into a(ny) String for the name's
key-value.`);
return 'Invalid Input.';
}
},
get name() {
return this._name;
}
};
Where it gets interesting is when you try to set/assign a new key-value for the _age property, because it has to meet the if conditional in order to be successfully assigned, meaning not all assignments are valid, etc.
person.age = 'twenty-eight'; /* output: twenty-eight is invalid for the
age's key-value. Change twenty-eight to/into a Number. */
console.log(person.age); // output: 27 (twenty-eight was never assigned)
person.age = 28; // output: none
console.log(person.age); // output: 28
Note how I was able to access the person._age property via the person.age property thanks to the getter method. Also, similar to how input for age was restricted to numbers, input for the name property is now restricted/set to strings only.
Hope this helps clear things up!
Additionally, some links for more:
https://johnresig.com/blog/javascript-getters-and-setters/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
https://www.infragistics.com/community/blogs/infragistics/archive/2017/09/19/easy-javascript-part-8-what-are-getters-and-setters.aspx