I'm still a novice when it comes to JavaScript and was trying to make my code more cleaner and was wondering why the top scenario works but the bottom doesn't? Am I missing something?
var partner = document.getElementById('partner');
var providedBy = document.getElementById('providedBy');
partner.style.display = "none";
providedBy.style.display = "none";
But this does not?
var partner = document.getElementById('partner');
var providedBy = document.getElementById('providedBy');
collection = partner + providedBy;
collection.style.display = "none";
In the console it gives me error saying Cannot set Property 'display' of undefined. Am I supposed to define it somewhere first? I console logged the new variable and it returned both div elements.
collection is of type string as the + operator automatically call for both their toString() function.
Now what you are trying is to access a property of collection.style which does not exist because you are operating on a string. That's the reason for the error message you are getting.
You could do something like:
var collection = [];
collection.push(document.getElementById('partner'));
collection.push(document.getElementById('providedBy'));
collection.forEach(function(element) {
element.style.display = 'none';
}
which would be something I think you are trying to archive.
just to complement the accepted answer, I think you should understand why you get this error.
For what i understand from your code, you are trying to set the css of both variables partner and providedBy to display : none.
Your first piece of code works because you do this separately, while in your second code you try to add with the (+) operator both nodes, which evaluates to the string "[object HTMLDivElement][object HTMLInputElement]".
Then you try to call .style on that string which evaluates to undefined, and then you try to call display on that undefined value, this is where you get the error.
You could leave your code just like that since there are not too many variables, but if you wanted to do something that worked on multiple variables you could
create an array
push your objects into the array
create a function that loops over the elements of the array and set their style.display = "none" to individually.
In JavaScript you have to declare all of your variables. Secondly, you can't point to two objects at once by using the + operator. JavaScript interprets this as trying to concatenate the two objects, which it can't do in this way. It will return the string [object Object][object Object]
In order to affect two Objects at the same time you would need to create a function or use an existing method.
Related
although it is a very simple code, I would like to get a full understanding of what is happening in my condition:
let getFreqOn = function(string){
//set a variable for object
let object = {}
for (let key = 0; key < string.length; key++){
// if (object.hasOwnProperty(string[key])) {
// if (object[string[key]]) {
// if (object[string[key]] !== undefined) {
if (string[key] in object) {
object[string[key]]++
}
else{
object[string[key]] = 1
}
}
return object
}
My main concern would be the first condition, I understand what it is they do but I cant put in to plain English how it is working. For example if (string[key] in object) is basically telling my that if a specific property is in the empty object I defined, then I will set then it will be set as the property and incremented. But what I'm trying to wrap my head around is that the object is empty, so how can the property be in the object?
Hoping someone can enlighten me on the conditions that I commented out as well. Sorry for the noob question.
First, the in operator returns a boolean result. It checks whether the string on the left is present as a property name in the object on the right.
Thus
if (string[key] in object)
asks whether that single character of the string is in use as a property name in the object. As you observed, the very first time through the loop that cannot possibly be true, because the object starts off empty.
Thus the if test is false, so the else part runs. There, the code still refers to object[string[key]], but it's a simple assignment. An assignment to an object property works whether or not the property name is already there; when it isn't, a new object property is implicitly created.
The key difference is right there in the two different statements from the two parts of the if - else:
object[string[key]]++; // only works when property exists
object[string[key]] = 1; // works always
I am looking at the Mozilla Developers website on the concept of the delete operator. In the last sub section of the page referring to “Deleting array elements” two similar scripts are shown, but the only difference in the scripts is how they modified the array.
In the first script, I quite don’t understand why “if” statement does not run. My current understanding is that delete operator “removes the element of the array”. If I were to type trees[3] in the console, it would return undefined in the console.
var trees = ["redwood","bay","cedar","oak","maple"];
delete trees[3];
if (3 in trees) {
// this does not get executed
}
The second script seems to "mimic" the delete, but not literally. Undefined is assigned to trees[3]. It doesn’t make sense to me how the “if” block runs in this script, but the first example does not. Can anyone help me understand this JavaScript behavior?
var trees = ["redwood","bay","cedar","oak","maple"];
trees[3] = undefined;
if (3 in trees) {
// this gets executed
}
There is a huge difference between the two methods you are trying:
Method 1:
You are deleting, destroying, completely removing the key 3 in your array called tree, hence there is no 3 in tree left, and the if check returns false.
Method 2:
You are assigning a new value to the key 3, which is undefined, there is still 3 in tree, and the if check returns true.
In your second example the key 3 still exists. It just holds a value that happens to be undefined. It IS confusing, but that's just the way Javascript is.
The in operator just checks if the key exists, not if the value is defined.
If you were to output the whole arrays after each of your "deletions" the first example would display something like this:
["redwood", "bay", "cedar", 4: "maple"]
Whilst the second example would print out something like this:
["redwood", "bay", "cedar", undefined, "maple"]
So as you can see, in your first example the key is completely missing and it continues with the next key which is 4. In the second example the key still exists, but it's value is set to undefined.
There is a difference between undefined which is set by the user and undefined which the javascript engine returns once something is actually undefined, meaning doesn't exist.
javascript can tell the difference between the two.
So in your example, when you do this:
var trees = ["redwood","bay","cedar","oak","maple"];
trees[3] = undefined;
if (3 in trees) {
console.log("hi");
}
javascript can tell that property 3 exists, but it was set to undefined by the user.
to prove so you have the following:
if (5 in trees) {
console.log("hi");
}
the property 5 of the array was never created, javascript knows it's undefined
by lack of creation and regards it as a property which doesn't exist, and therefore doesn't display the "hi"
if(3 in tree) {
//Stuff that won't get executed
}
is in fact correct, the thing is that in operator in Javascript does not work like in python, it simply checks if an object has a proprety. An array in javascript has a proprety 0, just like a string has a proprety 2 with the value someString[2].
the difference between delete object[prop]; and object[prop] = undefined; can be seen through object.hasOwnProperty(prop); or iterating through values or props of the object.
I wanna make a varible shortcut $$() so that i can use shortcut like $() [jquery] to save code in my project(ALL MY CODE IS PURE JAVASCRIPT).
when i put the string of id or class, it works all right, but when i put the tagName, it shows Cannot read property 'style' of undefined, it seems that the code is right,help,thanks
One more, is that way to defined a shortcut variable $$() to use in pure javascript environment right way? or is there any best practice to define a global variable like this?
window.onload = function(){
function $$(ele){
var pattern1 = /#/g;
var pattern2 = /\./g;
var pattern3 = /!/g;
var matches = ele.match(/[^#\.!]/g);//array
var elementS = matches.join("");
//alert(matches+elementS);
// console.log(document.getElementsByTagName(elementS));
var spaceExist = /\s/.test(elementS)
if(pattern1.test(ele)){
return document.getElementById(elementS);
}else if(pattern2.test(ele)){
//console.log(elementS);
return document.getElementsByClassName(elementS);
}else if(pattern3.test(ele)){
alert('hi');
console.log(elementS);
return document.getElementsByTagName(elementS);
}else if(spaceExist){
return document.querySelectorAll(elementS);
}
}
$$('#hme').style.backgroundColor = 'red';
$$('.myp')[0].style.backgroundColor = 'green';
$$('!h2')[0].style.display = 'none';//this not work,shows Cannot read property 'setAttribute' of undefined
}
<h1 id="hme">hi,friend</h1>
<p class="myp">mmdfdfd</p>
<h2>hhhhhh</h2>
Have you stepped through your code? Look at pattern #2:
var pattern2 = /./g;
That pattern will match any character at all given that's what the period represents in regular expressions - ref: http://www.regular-expressions.info/dot.html.
Therefore, this conditional is satisfied and returns its result:
else if(pattern2.test(ele)){
return document.getElementsByClassName(elementS);
}
Given there appears to be no element with a class name of h2 (which is the value of elementS), the return value is undefined.
Given that undefined has no properties, interrogating for the style property will produce the error you are seeing.
My advise is use one shortcut since you already using querySelectorAll:
window.$ = document.querySelectorAll.bind(document)
or if you rather need first element
window.$ = document.querySelector.bind(document)
this way you'll be able to do everything you are doing with normal css selectors and not obfuscated !tag for just tag
If speed actually matters, you will save some ticks by just having two aliases:
window.$ = document.querySelector.bind(document)
window.$el = document.getElementById.bind(document)
and calling $el when you need it specifically, instead of trying to make method polymorph.
Mister Epic's answer spots the main issue. Your h2 call is getting caught in that if statement, and that's why your error is happening. You need to make sure it doesn't get caught there, either by creating another pattern, or specifying in your second if statement that your 'ele' doesn't contain an '!'.
After that, in your third if statement:
else if(pattern3.test(ele)){
alert(hi); <---
console.log(elementS);
return document.getElementsByTagName(elementS);
The problem with this is you're going to alert(hi), but hi isn't defined. Make sure you wrap it in quotes.
Should be looking good after that.
I'm trying to sort out if this is plausible but have gotten syntax errors at best. So I am wondering if it is at all possible.
What I have is an object (example only)
var myObj = {
something1_max:50,
something1_enabled:false,
something1_locked:true,
something2_max:100,
something2_enabled:false,
something2_locked:true,
something3_max:10,
something3_enabled:true,
something3_locked:true
}
and what I want to do through a function is do something like again for example to sum things up..
function displayDetails(theScope, obj)
{
console.log(obj.[theScope]_max);
}
(function(){displayDetails('something3', myObj);})()
so when displayDetails() is called whatever the scope I can see in this example the max for that scope. In the console log for the example I would hope to see 10
Properties of JavaScript objects can always be accessed as a string using the bracket syntax, ie object['property']. This, of course, means you can build that string dynamically:
console.log(obj[theScope + '_max']);
Put the property name string in brackets.
console.log(obj[theScope + '_max']);
okay im working with a friend and he sent me js file which included a variable that included the ternary operator. I cant figure out how to change it to if..else. can you help please?
also i noticed ".length" didnt have the normal "()" after it, is there a reason why?
var nextRadioTab = activeRadioTab.next().length ? activeRadioTab.next() : $('#contentslider div:eq(0)');
Does this work?
if (activeRadioTab.next().length) {
var nextRadioTab = activeRadioTab.next();
} else {
var nextRadioTab = $('#contentslider div:eq(0)');
}
In JavaScript, objects are more-or-less just a list of names pointing to values. Each name-value pair is called a "property".
These values themselves can be any type of value, including a function. If the value of a property is a function, we call that a "method".
Say you want an object to track the x and y coordinates of a point.
var point = { x: 10, y: 20 };
In this case we can just use simple values, because we don't need any behaviour more advanced than getting a value (alert(point.x)) or setting one (point.x = 10).
jQuery is designed to let your code work on different browsers; different browsers behave differently in lots of situations, so jQuery can't just let you set
element.text = "hello world"
because depending on the type of object element is, it will need to modify different properties on different browsers. For this reason, jQuery makes you use methods for things like this:
element.text("hello world")
The .length attribute of a jQuery object is simple; it's controlled by jQuery itself and doesn't need to do any special things in different browsers. For this reason, you just use it directly. If they needed more complicated behaviour, they would use a function/method instead:
var myObject = { length: 2 }; // myObject.length
var myObject = { length: function() { return 2; } }; // myObject.length()
var nextRadioTab;
if (activeRadioTab.next().length)
nextRadioTab = activeRadioTab.next();
else
nextRadioTab = $('#contentslider div:eq(0)');
length is a property of whatever next() returns, which is most likely the same type of object as activeRadioTab.