I have a question on writing & using custom functions in lab.js studies:
I defined a function in a component at the beginning of the script and I’d like to use it in the following components in my study, but for some reason it doesn’t work.
I can call the function in the component where I defined it, but if I try to call it a few components later, it throws a ReferenceError and says the function is not defined.
Any clues what might be the issue here?
I think I’m not defining my function correctly at the beginning of the experiment but I’m not entirely sure. This is my code for the function:
const extend = function(array1, array2){
var array1, array2;
return Array.from(array1).concat(Array.from(array2));
}
This is how I call the function:
extend([1,2], [3,4,5]);
And this is where you can find the .json for the experiment:
https://github.com/MMarieSchuckart/stackoverflow_demo
Thanks in advance for any ideas/hints!
-Merle
Okay so I tried about 100 things and apparently, it's not enough to declare the function using const or var, you need to use window. to make it global.
The solution looks like this:
window.extend = function(array1, array2){
var array1, array2;
return Array.from(array1).concat(Array.from(array2));
}
Related
So, you know typeof, right?
What I want to do is create a function similar to that, and for this example let's just use a simple constructorof thing:
const constructorof = obj => {
return obj.constructor;
};
The syntax for it ends up being like this:
constructorof(someObjectOrWhatever);
But I want it to be like this:
constructorof someObjectOrWhatever;
Is there a way to do this?
No, you cannot create new keywords with custom logic in Javascript. You'll either need a function call, with the logic inside the function, or you'll need to inline the logic instead of calling the function. Either way, constructorof someObjectOrWhatever won't be valid syntax.
I've always used jquery with a
$(document).ready(function {
....
});
But i've recently just inherited a complete site with the script file opening like the following:
var gc = gc || {};
gc.header = {
mobileNav: function () {
...
},
headerLink: function () {
...
}
};
gc.header.headerLink();
I've never seen it structured in this way - it's actually quite easy to use and would love to learn more about to help improve my coding styles.
If somebody could help me by providing me with what this type of coding style is? And - if you know of any, some learning resources?
Thanks in advance!
Lew.
It is usually referred to as namespacing. It has absolutely nothing to do with jQuery.
This style of JavaScript syntax is a little more object oriented. This makes it easier to edit and read but also helps your JavaScript stay 'clean' by namespacing your JavaScript. This means that you basically try to keep as much of your JavaScript out of the Global Object as possible - thereby reducing collisions in your code.
Line by line:
var gc = gc || {}; // If a 'gc' object exists, use it. Otherwise create an empty object.
gc.header = { // In the gc.header object create 2 methods, mobileNav and headerLink
mobileNav: function () {
...
},
headerLink: function () {
...
}
};
gc.header.headerLink(); // Reference the headerLink() method inside gc.header
This is far preferable to creating a more flat pattern where mobileNav and headerLink are global functions because mobileNav and headerLink are very generic functions that may be used and named identically in other plugins. By namespacing you reduce the risk of breaking your code and running into collisions because gc.header.headerLink() is much more unique.
It`s just ordinary JavaScript, it's a technique called namespacing: How do I declare a namespace in JavaScript?
I have a class in javascript with a property that is a function. When I try to redefine that function like this:
myObject.someBehavior = function()
{
myObject.someBehavior();
extraLogic();
};
I am getting a "Too much recursion error". I understand why I am getting this error, the myObject.someBehavior is holding a reference to the function, so changing the function does not change the reference. So my question is how can I avoid this?
To clarify, I am trying to extend a behavior function of a javascript object. IN C#, I would just override the method, calling the base class's version first. Not sure how to do this in javascript.
You could achieve this with closures. I'm not sure whether it's a good idea for what you're trying to do though. You might be better off learning how inheritance works in JS.
myObject.someBehavior = (function(oldFunction) {
return function() {
oldFunction();
extraLogic();
};
})(myObject.someBehavior);
I've built a plugin that will use modules. Basically functions that can be added to the code in order to provide additional functionality.
In the plugin is a function to call these modules. Previously, I had called them like this:
processInstance($(doc).find('[data-bcp-crumbs]'), crumbs);
processInstance($(doc).find('[data-bcp-copyright]'), copyright);
processInstance($(doc).find('[data-bcp-activenav]'), activeNav);
The last part of each line is the name of a function that will be called within the processInstance script. So, I have the name of the function as both a string and a first-class object on each line. I would like to simplify that to something like this:
for (var i=0; i>module.length;i++) {
processInstance($(doc).find('[data-bcp-'+module[i].toLowerCase()+']'), window[module[i]]);
}
The module array is added to after each instance of the actual module code. I'm doing that like this:
module.push('crumbs');
This doesn't work because window[module[i]] is returning undefined.
How does my code need to be modified to make this work?
Here is an jsfiddle example of the entire plugin with a simple module inserted: http://jsfiddle.net/michaeljimmy/U8anp/1/
A colleague of mine helped me find the answer to this question. First, though, I noticed an error in the for loop. I had > instead of <. That didn't help. :)
The concept with the code was correct. The issue was scope. If you look at the jsfiddle, you'll see that the whole thing is in an enclosure, including the functions I was trying to call. So, there was no way window had access to the functions. We ended up making a couple simple changes.
First, along with module.push('crumbs'), or whatever the function name is, we added:
functions.crumbs = crumbs;
Then instead of using window[module[i]], we used
functions[module[i]]
Without the enclosure, window[module[i]] would have worked just fine.
I am getting an error when I run the following command in an included script. But if I run the command from the google chrome console, it works properly.
var a = {};
console.log(keys(a));
Error:
Uncaught ReferenceError: keys is not defined
What's going on here? How can I use the keys function in an included script?
console.log(keys(a))
keys() is not function provided by the browser for use in your code. You probably want Object.keys()
a = {};
console.log(Object.keys(a));
Sometimes the console has extra functions exposed to it for ease of use debugging that aren't available in your actual code. keys() sounds like one, and copy('some text') is another.
I'm failing to find a link which lists them, sadly. But I'm quite sure there are more than those 2 functions.
Whenever you get an error like this, try to search for a definition of the function/variable that's been reported as undefined. If it is defined, try looking for a reason this might not be working. Did you know that the keys function is apart of the Object constructor? You can't call it as if it's a free-standing function. Though if you get into the habit of doing this, try making your own function to allow this:
function key( object ) {
return Object.keys( object );
}
Your code should pass given a definition like this.