I came accross a following piece of code and i got confused and unable to understand the syntax used.
I would need help to break some hightlighted
let HT = HT || {}; //What is this syntax and what does it do ?
//Are we adding an Hexagon object to the object HT ?
HT.Hexagon = function(id, x, y) {
}
//Are we adding an object named Orientation to the object Hexagon ?
HT.Hexagon.Orientation = {
Normal: 0,
Rotated: 1
};
//Are we adding an object named Static to the object Hexagon ?
HT.Hexagon.Static = {
HEIGHT:91.14378277661477,
WIDTH:91.14378277661477,
SIDE:50.0,
ORIENTATION:HT.Hexagon.Orientation.Normal,
DRAWSTATS: false
};
How can one convert this piece of code to the modern ES6 classes ?
The first line code is using the or operator.
The operator checks first the expression on its left side - in this case the HT (it's probably an existing object.) If the expression is true e.g. holds a value like an object a number or a string etc, the expression will be assigned to the variable.
If HT does not hold any value which means it is false. Than it assign's the expression on its righte side - in this case an empty object.
The answer for your other three question is yes.
And it's not old JS at all.
Related
Unfortunately in this case 0 is false, so I can’t simply say if (x)
I’m hoping for something shorter than this to improve my code golf answer that’s shorter than these options
// check explicitly for 0
x||x==0
// isNaN
!isNaN(x)
I could remove the ! in isNaN by inverting the if else logic but the former is shorter anyway. Anything better?
UPDATE: It can be assumed that x is either undefined or a number. It by definition won’t be other truthy values such as the empty string.
To give a little more context I’m saving numbers (which will for certain be numbers do to problem restrictions) to an object than later checking that object at specified indices to see if it contains a number or undefined at the specified index.
You could check if it's nullish (null or undefined) using the ?? operator.
For example these two are equivalent:
if (x != null) {
/* statement */
}
x ?? /* statement */
In your specific case, you can also use it when assigning a value (x) onto your object (o) if the property (z) is not nullish.
o.z ??= x;
Got it! I can loosy compare against null on an object I have elsewhere.
i.e.
/// some object o I happened to have declared
/// Some random property I don't have on it such as z
x!=o.z
/// compiles to the following
x!=null
/// which will be false for numbers and true for undefined
I am puzzled with this one. I have the following code.
var s = "test";
s.len = 4;
var t = s.len;
The question is why the variable t has a value of undefined.
If you check the s.len after that code it is undefined.
If you check s the value is test. Not sure what is going on here. I am sure there is an explanation, but can't get my head around that and don't know how to search that.
For those who consider to vote down. This is a question we got in a course, and we are expected to prepare for the next session with this riddle.
I am not new to programming, but I fail to research how JavaScripts treats this code. It is valid code really, execute it in your Dev Tools and you will see.
I define a property for the string s called len assign to it the value 4. This property is, I believe created, but undefined. I would like to now why is it ? Is it specific to strings in JavaScript ?
but I fail to research how JavaScripts treats this code.
That is easy: strings are primitive types in JS, which means they don't have properties by themselves.
For . operator to work with them (e.g. for .length call) javascript defines such a thing called "wrapper objects".
So when you try to access a property of a primitive object - a temporary wrapper object is created that does behave as an object, hence you can access and assign properties to it.
The problem is that the wrapper object is temporary, so after it's used to access a property the object is discarded with all its state.
That's why when you assign a .len property you cannot access it on the next line: it's lost.
So a pseudo code for what actually happens behind the scenes for your code is
var s = "test";
(new String(s)).len = 4; // here you add an attribute for a new object
// and `s` is left untouched
var t = s.len;
The question is why the variable t has a value of undefined.
Because you have defined s as a string not as an object. so s.len should be undefined!
I am not sure what are you trying to do. But if you want to get the length of s then t = s.length will simply work.
I define a property for the string s called len assign to it the value 4. This property is, I believe created, but undefined. I would like to now why is it ? Is it specific to strings in JavaScript ?
You can find the answer from this question
run :
var s1 = "test";
console.log(typeof s1)//string
var s2 = {}
console.log(typeof s2)//object
s1.len = 4;
s2.len = 4;
console.log(s1.len);//undefine
console.log(s2.len);//4
I have the following test case in a coding kata for javascript:
*word-count_test.js
var words = require('./word-count');
describe("words()", function() {
it("handles properties that exist on Object’s prototype", function() {
var expectedCounts = { reserved: 1, words : 1, like :1, prototype: 1, and : 1, toString: 1, "ok?": 1};
expect(words("reserved words like prototype and toString ok?")).toEqual(expectedCounts);
});
});
The following code will not pass this:
code v1
var words = function(phrase) {
var wordCountAry = {};
// split on whitespace, including newline
phrase.split(/\s/).forEach(function(oneWord) {
if (!wordCountAry[oneWord]) {
wordCountAry[oneWord] = 1;
} else {
wordCountAry[oneWord]++;
}
});
return wordCountAry;
};
module.exports = words;
But something like the following counter line will not trigger the error:
code v2
wordCountary[word] = (+wordCountary[word] || 0) + 1
So what is so special about that unary "+" operator?
A standard JavaScript object prototype has predefined properties, such as:
toString()
constructor()
When you test those property names using typical conditional logic, they will appear as existent, e.g.
var x = {};
if (x['toString']) {
// this gets executed
}
The second code sample works around that issue with two tricks:
+x['toString'] || 0;
First, the property is coerced into a numeric value by using the unary plus operator. For functions or undefined values, the coercion yields NaN.
Secondly, the logical or operator is used to coalesce the left hand and right hand expression; if the right hand operand evaluates to false (that includes NaN) it will yield the right hand operand, otherwise it returns the left hand operand.
In this manner, either an undefined property value or a function value will yield 0 and therefore it will work as expected.
It's not really about "reserved" names (those are another matter in JavaScript, e.g. class although it's not reserved anymore in ES6), but about inherited properties.
wordCountAry is an object, so it already has a toString method. So when you test
if (!wordCountAry[oneWord])
with the words "toString" the condition will be false (because wordCountAry["toString"] is trueish (it's a function).
So you need to use a condition that will work when the property is not a number (which is the case with the Number coercion of a function with unary +), or, to be safer, also check if it is inherited (hasOwnProperty).
When you are creating your wordCountAry object, you can can pass null as the prototype, and this should solve your problem. So, instead of initializing it to {}, see how you can set it's prototype to null.
The following JavaScript...
if (eval('typeof admin_post_css_theme_dark-moon)=='function')) {/**/}
...triggers the following error message...
Error: ReferenceError: moon is not defined
The only thing I can really differentiate in this situation is that other themes don't have a dash in their names...
if (eval('typeof admin_post_css_theme_silver)=='function')) {/**/}
...doesn't trigger any errors.
So how is the dash between 'dark' and 'moon' triggering this error?
Edit: I wanted to take a moment and recommend that others who encounter this should adapt camelCase or something similar. In general I use a 'name' and a 'base' myself. The 'base' is the URL-friendly version of something that the 'name' includes URL unfriendly characters. In example 'My Example' and 'my-example' or 'my_example'.
http://en.wikipedia.org/wiki/CamelCase
JavaScript variable names can't contain dashes, object properties however can. For instance, something like this would work:
var themes = {
'admin_post_css_theme_dark-moon': function () {},
'admin_post_css_theme_silver': function () {}
};
if (typeof themes['admin_post_css_theme_dark-moon'] === 'function') {
/**/
}
Primarily because '-' is not a valid identifier in javascript, its the minus sign. Your eval in essence is trying to get the typeof the expression admin_post_css_theme_dark minus moon. Valid identifiers (i.e. variable, function or object names) in javascript are [A-Za-z0-9_$] but cannot start with a number (note this is a regex, and the hyphens in this context mean range i.e. a to z, just in case it was unclear)
My evolution to the question would be how would you have expected admin_post_css_theme_dark-moon to be defined, as you are expected it to be somehow/where in code, then in turn to test if it is a function.
As it would be absolutely impossible to do this
var admin_post_css_theme_dark-moon = function(){...};
//or
admin_post_css_theme_dark-moon = function(){...};
however it is possible to do this.
window['admin_post_css_theme_dark-moon'] = function(){...};
or preferably use your own object
var Themes = {};
Themes['admin_post_css_theme_dark-moon'] = function(){...};
//or
var Themes = {
'admin_post_css_theme_dark-moon' : function(){...};
}
As object properties if referenced by string index (i.e. between [] as a string) are not bound by the identifier rules.
then of course your eval would have to change also
something like
if (eval("typeof window['admin_post_css_theme_dark-moon']")=='function')) {/**/}
//or
if (eval("typeof Themes['admin_post_css_theme_dark-moon']")=='function')) {/**/}
NOTE the use of alternating " and ' so you don't have to escape
I changed...
eval('typeof '+my_object)=='function')
...to...
eval('typeof \''+my_object+'\'')=='function')
I didn't have the chance to edit this in so the question could be more concise. For those looking at just this answer check out the other answers from OJay and sabof as they are wholly relevant.
I would call myself an intermediate jQuery developer, but I'm confused about what this line (from Twitter's Bootstrap) is doing:
$tip.find('.help-popover-title')[ $.type(title) == 'object' ? 'append' : 'html' ](title)
Specifically, the part between the square brackets. Can anybody explain it to me?
$tip // tip object
.find('.help-popover-title') // find elements of this class
// if the data inside the title variable is an object
// use the append method otherwise use html method
[$.type(title) == 'object' ? 'append': 'html']
(title) // lastly, execute the selected function and pass in the title var
The inner statement uses a ternary operator. It's basically a single line if..else statement
x = 5;
x === 5 ? true : false; // true
x === 4 ? true: false; // false
Since the selected method is inside the brackets, you can use a string to select a method
It's equalvelent to:
$tip['append'](title) === $tip.append(title)
The big concept here is that object properties can be accessed not just literally and directly but also with square brackets containing a String (literal or variable) with the name of the property. Also, functions are always properties of an object—even if only the global context.
First, check out value-based properties:
var myobj = {
animal: 'frog',
color: 'blue',
fly: function() {/*fly*/},
hide: function() {/*hide*/}
};
alert(myobj.animal); // alerts 'frog';
var prop = 'color';
alert(myobj[prop]); // alerts 'blue';
Then note that when the property values are functions it doesn't change anything. They are still accessed the same way:
myobj.fly() // run function fly
prop = 'hide';
myobj[prop]() // run function named in variable 'prop', which is 'hide';
So ultimately, the code fragment you posted is just checking the type of the title variable and choosing the appropriate function to make it a child of the found element. If the title is an object, append it. If it's not (it must be text) then use the html function instead. It was coded this way to save duplicating code or declaring a new variable.
Ternary operators are the expressive forms of normal procedural if statements (that is, they evaluate to something rather than controlling flow). The following example will show this:
if (a == 1) {return 'yes';} else {return 'no';}
return (a == 1) ? 'yes' : 'no';
VB's Iif() function and Excel's IF() worksheet function are exactly equivalent.
It's an inline if statement, otherwise called a ternary operator. Basically, if the type of title is 'object' then it's getting the index 'append', otherwise the index 'html'. Hope this what you meant by your question.