I am making a website for school and we where working with function. Now i got a litle "problem"
i am using jquery to change the DOM and made a function where you can choose which location you are adding the element to.
Something like this:
function functioname(parameter){
console.log(parameter);
}
when i call this function like this:
functioname("#id");
i will return "#id";
But if i call it like this:
functioname (id);
I get return with the whole div and his children. How can this happen?
And why works this only with divs.
It isn't really a problem i was just wondering how this works.
Thanks in advance if somebody could explain what is happening here.
The window.id will find a DOM element whose id it matches. For example, window.mydiv will find:
<div id="mydiv"></div>
However, this not a recommended practice.
As a general rule, relying on this will lead to brittle code. Which IDs end up mapping to this API can vary over time, as new features are added to the Web platform, for example. Instead of this, use document.getElementById() or document.querySelector().
http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
In the first function you are passing the string and in the second example you are passing the window object. Same as we pass an object with "this"
<div onclick= " functionname(this); "> </div>
here we get the complete object inside the function.
In first line of code "#id" you are passing the string. it's return the string also as you says.
in second you pass object id that you have earlier in your code. This is maybe why you got the different result.
Let's take a look at the window object. The window is pretty cool in that it allows you to declare global variables from anywhere on the fly. Take the following code for example
//the following three lines of code do the same thing
//create a global variable and store a value in it
window.a = 1;
window["b"] = 2;
var c = 3; //this one is most used though
function g() {
//the following three lines of code do not do the same thing
window.d = 4; //global
window["e"] = 5; //global
var f = 6; //local
}
g();
console.log(a); //prints 1
console.log(b); //prints 2
console.log(c); //prints 3
console.log(d); //prints 4
console.log(e); //prints 5
try {
console.log(f); //ERROR
} catch (err) {
console.log(err);
}
console.log(window.a); //prints 1
console.log(window.b); //prints 2
console.log(window.c); //prints undefined
console.log(window.d); //prints 4
console.log(window.e); //prints 5
console.log(window.f); //prints undefined
console.log(window["a"]); //prints 1
console.log(window["b"]); //prints 2
console.log(window["c"]); //prints undefined
console.log(window["d"]); //prints 4
console.log(window["e"]); //prints 5
console.log(window["f"]); //prints undefined
It is important to know that obj.prop === obj["prop"] is always true in JavaScript. That is why the last two sets of tests have the same results. Also important is prop === window.prop unless you declared prop using var prop;. This is because JavaScript secretly uses the special keyword using on the window variable at all times unless otherwise specified.
All browsers make DOM elements available via id using document.getElementByID but some browsers are nice enough to set up some variables for you so you don't have to write all that code. Imagine that a browser runs this script before any of your scripts do
(function(context) {
var tags = document.getElementsByTagName("*");
for (var i = 0; i < tags.length; i++) {
var tag = tags[i];
if (tag.id) {
context[tag.id] = tag;
}
}
}(window));
Which fills the window variable / global scope with tags that have ids.
Here are a bunch of examples. http://jsfiddle.net/Lk345zez/
Related
Good Day,
I am working on a pet project using NodeJS and Electron. It is basically a simple text editor at the moment. However I am running into an issue when trying to pass the value of a text-area to a function prior to saving to file.
Specifically when I call a function in another module, the value of the contents becomes 'undefined'. I suspect I am passing it incorrectly, or that it is being over-written between when I make the call and when the call executes, since strings are supposed to be passed by reference.
The code for the Renderer(index.html) is like this :
let otherModule = require('./js/otherModule.js');
let $ = require('jquery');
$('#btn_Save').on('click',() => {
// get the fileName, if empty propmt user with save dialog,
//log it to console for debugging
var contents = $('#txt_Content').val();
console.log('with:',contents.substring(0,9),'...');
var finalContents = contents; // (create a copy?)
if(//someConditionMet//)
{
var otherVar = $('#txt_Other').val();
console.log('Use:',otherVar.substring(0,9),'...');
finalContents = otherModule.someFunc(contents, otherVar);
}
//do something with final contents.
})// end of On-click
I have used console.log() to extensively evaluate the function and can confirm that up to the call to otherModule, the contents are correct, and match those in the textArea.It is once we are in the 'otherModule' that things go awry.
The code for the otherModule is like this:
const someFunc = function(contents, otherVar)
{
console.log('DoThings with:',contents.substring(0,9),'...');
// print shows the value to be undefined...
// do more things
console.log('Did stuff with otherVar:',otherVar.substring(0,9),'...');
// prints just fine as as expected.
// do more things
return someString;
}
module.exports = {
someFunc: someFunc
}
As mentioned in the comment, the very first line of the function logs the contents of the console, which displays the substring as 'undefined'.
Thank you for your time and your consideration!
// Extra context//
I have done some searching but beyond learning that strings are passed by reference and are immutable, I have not seen an answer to a question like this. There has been some discussion of closure issues, but usually in the context of events and callbacks, which I do not believe is the context here.
// Extra Information//
I have since found a solution to get my parameters to pass correctly. I have posted the answer below. I did two things:
1. Changed the function definition from 'const' to 'let'
2. Changed the order of the params, and removed the space following the comma.
If you get the value inside the if you should be fine.
if(//someConditionMet//)
{
var contents = $('#txt_Content').val(); //New line
var otherVar = $('#txt_Other').val();
console.log('Use:',otherVar.substring(0,9),'...');
finalContents = otherModule.someFunc(contents, otherVar);
}
I have found a solution to this problem. I am not certain why it makes a difference but I changed two things in 'otherModule'.
1. I changes the function from 'const' to 'let'
2. I changed the order of the parameters, removing the space after the comma
The new function header looks like:
let someFunc = function(otherVar,contents) {...}
I also updated the call to match the new order ( given):
finalContents = otherModule.someFunc(otherVar,contents);
I hope this helps someone in the future!
Is this
var result = XrmServiceToolkit.Soap.Execute(setStateRequest);
just storing the function into the variable,
executing and storing the return value into the variable,
or doing both?
Unfortunately I wasn't able to find something useful in the internet. Looking at http://xrmservicetoolkit.codeplex.com/wikipage?title=Soap%20Functions
it looks like the function is executed but i am not sure.
I also tested it with a normal Javascript inside the chrome browser and got this result:
> function test(a){
console.log(a);
};
undefined
Calling the function normal
> test("asd");
asd
With a variable declaration
> var x = test("asd");
asd
But it looks like the variable does not contain any information
> console.log(x);
undefined
> x
undefined
Now I am completely confused. Why is the function called as variable when it is never stored? I am new to Javascript and need to understand what this is exactly doing.
It is storing the return value of the function into a variable.
The reason your test function is not working is because you don't return a value in test.
function test(num) {
return num * 2;
}
var doubled = test(2);
// doubled now contains 4
var doubleVariable = test;
// doubleVariable is now the same as test
doubleVariable(2)
// returns 4
This article may clarify things a bit more
very basic JavaScript programmer here!
I was busy on some code with variables that look like this:
blocktype1;
blocktype2;
blocktype3;
blocktype4;
... //everything between blocktype4 and blocktype70, the three dots are not actual code!
blocktype70;
Now I was using eval() in a function where a value was given to one of the blocktype variables. The blocktype depended on the variable "number".
This is what I had for that part:
eval("blocktype" + number) = 3
What I want is, say "number" is 27, then I want the variable blocktype27 to get a value of 3.
When I check the console it says:
ReferenceError: Invalid left-hand side in assignment
Could anyone possibly help me?
I would prefer just vanilla JavaScript and still the use of eval.
Thank you for your time!
The 'correct' solution would probably be to use an Array which is ideal for sequences and are accessible by index.
var number = 1;
var val = 3;
var blocktype = []; // so clean
blocktype[number] = val;
However, properties can be accessed as with the bracket notation as well. This assumes the variables are in global scope and are thus properties of the global (window) object.
var blocktype1; // .. etc
window["blocktype" + number] = val;
The problem with the eval is that is effectively the same as doing f() = 3 which does not make sense: only variables/properties can be assigned to1.
However eval is a built-in function and the results of a function cannot be assigned to, per the error message. It could be written as
var blocktype1; // .. etc (see dandavis' comment)
eval("blocktype" + number + " = " + val);
// What is actually eval'd is:
// eval("blocktype1 = 3")
which quickly exposes a flaw with eval. If val was the string "Hello world!" with would result in eval("blocktype1 = Hello world!") which is clearly invalid.
1 For the gritty: the left-hand side of an assignment has to be a Reference Specification Type, which is a more wordy way of describining the above behavior. (It is not possible for a JavaScript function to return a RST, although it could technically be done for vendor host objects.)
Feel free not to accept this, since it's specifically not using eval(), but:
You can allocate an array of size 71 like so:
var blocktype = new Array(71);
(your number values apparently start at 1, so we'll have to ignore the first element, blocktype[0], and leave room for blocktype[70], the 71st)
You can now assign elements like this:
blocktype[number] = 3;
and use them like so:
alert( blocktype[number] );
I have a weird behavior on my arms :
I declare an object, properties shall execute in sequence, which they do, but in one there is a simple pass through nothing written in it happens.
Do I have a scope problem ?
Here is a code fragment where verteX is my object
stepsCalcul: function() {
var test = 2;
verteX.testCheck = test*2; //returns undefined
alert('stuff') //alerts nothing
console.log("logged stuff")//logs nothing
verteX.mouseCoordinates();
return true;
},
I sort a jsFiddle aswell
http://jsfiddle.net/AEWrK/3/
Thanks!
Based on your fiddle, you're not calling the init function.
Replace verteX.init; with verteX.init();
Is it possible to find the name of an anonymous function?
e.g. trying to find a way to alert either anonyFu or findMe in this code http://jsfiddle.net/L5F5N/1/
function namedFu(){
alert(arguments.callee);
alert(arguments.callee.name);
alert(arguments.callee.caller);
alert(arguments.caller);
alert(arguments.name);
}
var anonyFu = function() {
alert(arguments.callee);
alert(arguments.callee.name);
alert(arguments.callee.caller);
alert(arguments.caller);
alert(arguments.name);
}
var findMe= function(){
namedFu();
anonyFu();
}
findMe();
This is for some internal testing, so it doesn't need to be cross-browser. In fact, I'd be happy even if I had to install a plugin.
You can identify any property of a function from inside it, programmatically, even an unnamed anonymous function, by using arguments.callee. So you can identify the function with this simple trick:
Whenever you're making a function, assign it some property that you can use to identify it later.
For example, always make a property called id:
var fubar = function() {
this.id = "fubar";
//the stuff the function normally does, here
console.log(arguments.callee.id);
}
arguments.callee is the function, itself, so any property of that function can be accessed like id above, even one you assign yourself.
Callee is officially deprecated, but still works in almost all browsers, and there are certain circumstances in which there is still no substitute. You just can't use it in "strict mode".
You can alternatively, of course, name the anonymous function, like:
var fubar = function foobar() {
//the stuff the function normally does, here
console.log(arguments.callee.name);
}
But that's less elegant, obviously, since you can't (in this case) name it fubar in both spots; I had to make the actual name foobar.
If all of your functions have comments describing them, you can even grab that, like this:
var fubar = function() {
/*
fubar is effed up beyond all recognition
this returns some value or other that is described here
*/
//the stuff the function normally does, here
console.log(arguments.callee.toString().substr(0, 128);
}
Note that you can also use argument.callee.caller to access the function that called the current function. This lets you access the name (or properties, like id or the comment in the text) of the function from outside of it.
The reason you would do this is that you want to find out what called the function in question. This is a likely reason for you to be wanting to find this info programmatically, in the first place.
So if one of the fubar() examples above called this following function:
var kludge = function() {
console.log(arguments.callee.caller.id); // return "fubar" with the first version above
console.log(arguments.callee.caller.name); // return "foobar" in the second version above
console.log(arguments.callee.caller.toString().substr(0, 128);
/* that last one would return the first 128 characters in the third example,
which would happen to include the name in the comment.
Obviously, this is to be used only in a desperate case,
as it doesn't give you a concise value you can count on using)
*/
}
Doubt it's possible the way you've got it. For starters, if you added a line
var referenceFu = anonyFu;
which of those names would you expect to be able to log? They're both just references.
However – assuming you have the ability to change the code – this is valid javascript:
var anonyFu = function notActuallyAnonymous() {
console.log(arguments.callee.name);
}
which would log "notActuallyAnonymous". So you could just add names to all the anonymous functions you're interested in checking, without breaking your code.
Not sure that's helpful, but it's all I got.
I will add that if you know in which object that function is then you can add code - to that object or generally to objects prototype - that will get a key name basing on value.
Object.prototype.getKeyByValue = function( value ) {
for( var prop in this ) {
if( this.hasOwnProperty( prop ) ) {
if( this[ prop ] === value )
return prop;
}
}
}
And then you can use
THAT.getKeyByValue(arguments.callee.caller);
Used this approach once for debugging with performance testing involved in project where most of functions are in one object.
Didn't want to name all functions nor double names in code by any other mean, needed to calculate time of each function running - so did this plus pushing times on stack on function start and popping on end.
Why? To add very little code to each function and same for each of them to make measurements and calls list on console. It's temporary ofc.
THAT._TT = [];
THAT._TS = function () {
THAT._TT.push(performance.now());
}
THAT._TE = function () {
var tt = performance.now() - THAT._TT.pop();
var txt = THAT.getKeyByValue(arguments.callee.caller);
console.log('['+tt+'] -> '+txt);
};
THAT.some_function = function (x,y,z) {
THAT._TS();
// ... normal function job
THAT._TE();
}
THAT.some_other_function = function (a,b,c) {
THAT._TS();
// ... normal function job
THAT._TE();
}
Not very useful but maybe it will help someone with similar problem in similar circumstances.
arguments.callee it's deprecated, as MDN states:
You should avoid using arguments.callee() and just give every function
(expression) a name.
In other words:
[1,2,3].forEach(function foo() {
// you can call `foo` here for recursion
})
If what you want is to have a name for an anonymous function assigned to a variable, let's say you're debugging your code and you want to track the name of this function, then you can just name it twice, this is a common pattern:
var foo = function foo() { ... }
Except the evaling case specified in the MDN docs, I can't think of any other case where you'd want to use arguments.callee.
No. By definition, an anonymous function has no name. Yet, if you wanted to ask for function expressions: Yes, you can name them.
And no, it is not possible to get the name of a variable (which references the function) during runtime.