Classless object in shorthand notation - javascript

So, I dived head first in Marijn Haverbeke's Eloquent Javascript and swam directly to the Electronic Life chapter.
There we observe the spontaneous generation of an object :
{"#": Wall,"o": BouncingCritter}
Wall and BouncingCritter are defined elsewere :
function Wall() {}
function BouncingCritter() {
this.direction = randomElement(directionNames);
this.name = word();
};
BouncingCritter.prototype.act = function(view) {
if (view.look(this.direction) != " ")
this.direction = view.find(" ") || "s";
return {type: "move", direction: this.direction};
};
BouncingCritter.prototype.toString=function(){
return this.name +"\t"+ this.direction;
}
---> I don't get what sorcery is happening there.
Well, I see we're creating an object on the fly, and since it's going to be used only once, no need to define a class. OK.
I understand that hitherto this anonymous object has two properties, which are themselves classes, that will be instantiated several times down the road. I'm starting to flutter but I'll get along. One of those (Wall) is quite empty, which will later prove useful as "nothing" is somewhat better than 'undefined'. Fine.
What I don't get is the use of string constants "#" and "o" on the left hand side of the colon. Could someone please expand on this ?
Heartly thanking,

What I don't get is the use of string constants "#" and "o" on the left hand side of the colon. Could someone please expand on this ?
The property has to be called something. Those are just rather unhelpful names which tell you nothing about what the property actually holds.
… until you look at the context. From the link you provided:
The “#” characters in this plan represent walls and rocks, and the “o” characters represent critters.
It's using # as the name for the wall property because that is the symbol used to render it in the UI. Ditto "o"/citter.
(That still isn't a great name though: It tightly couples the internal name to the presentation of it, which would start to fall apart if the UI was later changed to use (for example) pretty graphics instead of ASCII art)

In this scenario it's more like a dictionnary. It just use to say that the character # or o represent respectivly the class Wall and BouncingCritter.
Edit (after reading your book as fast as i could): When he instanciate the World(map, legend), legend is the dictionnary. Later in the code he creates the grid and for every characters from the string representation of the world, he instanciates the correct class according to the legend dictionnary he gave var element = new legend[ch]();.

OK folks, thanks for your answers. I dug a bit further and came across a very clear and concise (nifty, indeed) explanation as to the ways of the object literal notation : Nifty Javascript - Objects.
What confused me most at first in
{"#": Wall,"o": BouncingCritter}
are the quotes surrounding properties names, and the fact that "#" would otherwise be an illegal character for a property name.
To wrap my head around this, I had to write it down, and I share below, for what it's worth.
The "legend" is anonymous classless object defined, when we construct the World,
by the block {"#": Wall,"o": BouncingCritter}
Says Marjin :
A legend is an object that tells us what each character
in the map means. It contains a constructor for every
character—except for the space character, which always
refers to null, the value we’ll use to represent empty
space.
In the World constructor, we populate the grid.space array according to what we
read from the 'map' (which is instantiated by the array 'plan').
The character read from the map (either 'o' or '#') serves as the key in the
hashtable (a.k.a "object") 'legend'. The corresponding value is a class (either
'Wall' or 'BouncingCritter') which is then instanciated. The resulting object is
finally stored in the grid.space array.
Note that the original literal notation {"#": Wall,"o": BouncingCritter} for
creation and the subsequent employ of square brackets in the function
'elementFromChar'
var element = new legend[ch]();
allows for the use of the
otherwise illegal character '#' as the name of the property.
Here be rant :
Needless to say, I'm not very happy with all this. I guess it's the kind of stunt that gives javascript a bad reputation sometimes. All in all, I'm starting to consider that the title of the book, "Eloquent Javascript", may be a little overstated or even plain misleading.
Granted, it is an impressive demonstration of object-fu maestria, but neither the code nor the text are specially clear. I had a very hard time stitching the code patches together and getting the project to work and I feel that the object breakdown used to model the problem is overly complicated. But heck, I'm learning, so my opinion is completely unauthorized ;-)
end-of-rant

Related

What is the name of the parameter of String Object in JS?

I have been studying coding for 3 months and this is my first question to ask here. I am coding an application that will help Turkish learners conjugate Turkish words. I wrote some of the code using procedural way with functions, and now I want to refactor the code with OOP. Thus, I created a class and extended it to String class (Because I want to be able to use string methods for words). Then I wrote some public fields related to my class name.
class TurkishLettersData extends String
turkishAlphabet = {
v: {
voicing: "voiced",
...
},
ş: {
voicing: "voiceless",
...
}
}
The object goes much longer than that and there are several arrays following the object. I will use the object for word conjugation. More on that below.
As I wanted to use the parameter of the String class, I did not write a constructor function or super function. I can still use the parameter of String class while creating an instance.
When I wanted to add a method that would find the first letter of words, I encountered this problem. Basically, I want to code the part below:
findFirstLetter() {
return this.xxxxx.at(0)
}
However, as I do not know the name of the parameter of the String object, I cannot write any method to my class.
I searched the internet and asked the same question to ChatGPT to no avail.
So, what is the name of the parameter of String Object in JS?
EDIT:
Thank you everyone. I could solve my problem for now following Felix Kling's suggestion (return this.at(0)). I will check Bergi's idea of using composition and edit the question again.
I will use the turkishAlphabet object for word conjugation. For instance, the prepositions in on at are translated to Turkish as -de or -te suffixes (there are more though.) Even though the suffixes mean the same, the final letter of the word these suffixes will be used affects which one to use and there are several conditions for it. If the word ends with a voiced consonant (ev for house), we say evde (at the house), but if it ends with a voiceless consonant (iş for work), we say işte (at the work). A findLastLetter() method will find the last letter and check whether that letter is voiced or voiceless. This is just a small example.

What is the purpose of this CanvasJS code line? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am using CanvasJS and always used these lines here:
var chart = new CanvasJS.Chart("chartContainer",
{
...
});
chart.render();
Unfortunately, I do not know what these lines are doing. Can someone explain it to me? Thank you very much!
What are these lines doing??
Well on their own not much. In the context of a javascript engine a lot or not much.
The short version.
Creates and renders a CanvasJS.Chart, putting the chart in the DOM element identified as "chartContainer". Well it would if it was complete.
The long version.
var is a javascript token. It is used to declare a variable and is usually followed by the name or variable identifier of the variable. In this case chart. You could also use the tokens let, const, or function (and some others) which have different scope and access to the contents of the variable they declare
= is an assignment operator. It moves the data from the expression on the right to the variable/property on the left.
new (javascript token)is a special token that modifies the way a function is called (In days of old when javascript was still considered a toy it was used to make javascript look hip and cool) It is rather superfulouse in the language so you can ignore it for now.
CanvasJS (variable identifier) is a variable that was declared somewhere in the javascript code (hopefully) using one of the declaration tokens (most likely function). It has been capitalised which is significant. In Javascript when you capitalise a variable identifier you are telling the world that this is a special function that will always return an Object if called. It also tells you that it might have a special property called prototype which helps the javascript engine run your code a little quicker and helps you by simplifying your data structures using something called inheritance.
.Chart (property identifier) This is a property, the dot "." between CanvasJS and Chart signifies property of (called Dot notation, but could equally have been the not so popular, Bracket notation CanvasJS["Chart"] same as CanvasJs.Chart. )
So Chart is a property of CanvasJS. A property is like a variable but rather than being alone the property is attached to an Object. This is very handy for grouping related data and information
Because CanvasJS has a big C, Chart is most likely (but not a certainty) one of the special prototype properties of CanvasJS.
( Opening brace. When you see one of these after a variable identifier it means that the variable is a function that can be called. It at some point must have a closing brace ) What is between ( and ) are called function parameters, or arguments and are passed to the function. There is a whole set of rules governing what goes between the ( and ) and way to much to cover now.
Calling a function does a lot of special stuff, in the most basic terms the javascript engine locates that code that belongs to the function, packs its bags with arguments, goes to the function code, sets up camp, executes the function code and then returns with all the groover holiday shots. Anyways I digress
"chartContainer" first argument, a string literal. It is abstractly a devoted bit of memory that holds a "string" of characters. Strings and string literals have many uses, but looking at the content of this string I can guess what it is used for.
It is an identifier, name, or query used to find a DOM object (Document Object Model, the ugly bit hanging of the side of javascript, the dude whose party Javascript came to but nobody likes and wishes would go away) The bit of HTML that will hold the chart
, comma used to separate arguments (in this case)
{ Opening curly or Object literal. Like the string literal but instead of characters it contains properties. needs to have a closing curly at some point
... the dots by themselves in this context is just gibberish and will cause the javascript parser to stop dead in its tracks and not look at anymore code. We know it's gibberish, so does javascript, but rules are rules so we need to clean this up.
//... commented epsilon referring to the missing code.
} closing object literal.
) end of function's argument list.
; End of expression, like new it is not really needed but god (AKA Douglas Crockford) linted that it must be so, or you will be smittened by the obscure bugs and the taunts of JSLint and friend forever. (also you can not see return characters, so ; tells you this statement/expression/blockless code block, is complete.)
At this point javascript will call the function CanvasJs.Chart passing the arguments, a string and an object. The function will do its thing and with luck will return a object (we know it will be an object because the new token and that Chart has a big C). The = will give the variable identified as chart (note the small c) a referance to the returned object.
chart.render() Property of referenced object held by chart called render is a function, call it with no arguments. I am guessing that it draws a chart and that chart can be seen in the DOM inside an element that may have the id chartContainer.

Understanding ES6 Symbols

I've been around the block when it comes to languages, having worked with everything from C# to Lisp to Scala to Haskell, and in every language that supported them, symbols have acted pretty much the same; that is, any two symbols with the same name, are guaranteed to be identical because they're singleton objects.
Racket: (equal? 'foo 'foo) true
Common Lisp: (eq 'foo 'foo) true
Ruby: :foo == :foo true
Scala: 'foo == 'foo true
ES6: Symbol('foo') === Symbol('foo') false
The benefit of symbols being singletons is obvious: You can use them in maps/dictionaries without risking your key not being equal to your input because the language suddenly decided to hash it differently (looking at you, Ruby)
So why is it that ECMAScript 6 takes a different approach on this, and how can I get around it?
You can (sort-of) get the effect of symbols being "knowable" by name by using registered (global) symbols:
var s1 = Symbol.for("foo");
var s2 = Symbol.for("foo");
s1 === s2; // true
Of course you can create your own Symbol registry too, with a Map instance or a plain object.
edit — I'll add that the intention of the optional string parameter when making a new Symbol instance is to provide a way of identifying the meaning and purpose of a symbol to the programmer. Without that string, a Symbol works just fine as a Symbol, but if you dump out an object in a debugger the properties keyed by such anonymous Symbol instances are just values. If you're keeping numeric properties on an object with Symbol keys, then you'll just see some numbers, and that would be confusing. The description string associated with a Symbol instances gives the programmer reference information without compromising the uniqueness of the Symbol as a key value.
Finally, you can always compare the result of calling .toString() on two similarly-constructed Symbol instances. I suspect that that practice would be considered questionable, but you can certainly do it.
edit more — it occurs to me that the fact that the default behavior of Symbol creation in JavaScript makes the type more useful than, say, atoms in Erlang or keys in Clojure. Because the language provides by default a value guaranteed to be unique, the fundamental problem of namespace collision is solved pretty nicely. It's still possible to work with "well-known" symbols, but having unique values available without having to worry about conflicts with other code that might also want to avoid collisions is nice. JavaScript has the somewhat unique, and certainly uniquely pervasive and uncontrollable, problem of a global namespace that may be polluted by code that a programmer does not even know exists, because code can collide in the browser enviroment due to the actions of a party different from, and unknown to, an arbitrary number of software architects.

Using reserved words as property names, revisited

Can a reserved word be used as an object's property name?
This issue was raised indirectly in a previous Stack Overflow question: Browser support for using a reserved word as a property name in JavaScript. The answer seemed general consensus by Alex Wayne:
You can use those words, but only as strings and not shorthand
properties.
foo['class']; // cool
foo.class; // not cool
While I think that they are probably more knowledgeable than me in this area and it is probably a bad idea to use reserved words in some situations, I think their conclusion is wrong based on two points:
testing of the reserved words using them as a "shorthand" properties
the HTMLFormElement makes it impossible not to use reserved words in "shorthand"
First, using the reserved word list, each was added as a property to an Object and HTMLElement, both as obj["word"] and obj.word, and then retrieved as obj["word"] and obj.word. In each of the 63 cases all eight tests worked correctly.
Second, the HTMLFormElement necessitates this works because it retrieves in its elements using shorthand notation. If <input name='typeof' value='scalar' /> is an element of a form, then form.typeof == "scalar".
From my experience, reserved words are usually data inflicted (e.g. a column named "private"), not program inflicted. As such they contaminate JSON objects, and from there input, and from there the HTMLFormElement. Simply put, without a huge amount of (IMHO unnecessary) work, it's impossible to keep reserved words not being forced to work correctly in shorthand.
It seems to me these real problems:
care needs to be taken not to conflict with existent properties, not reserved words
(many if not all) variables cannot be reserved words
use of reserved words as properties can be (but are not necessarily) confusing
Is this conclusion correct then, that reserved words as property names, and accessing them either as strings or shorthand, is just fine - as long as a little common sense is applied to the situation?
In ECMAScript, starting from ES5, reserved words may be used as object property names "in the buff". This means that they don't need to be "clothed" in quotes when defining object literals, and they can be dereferenced (for accessing, assigning, and deleting) on objects without having to use square bracket indexing notation.
That said, reserved words may still NOT be used as identifier names. This is stated quite unambiguously in the spec and is stated somewhat emphatically here (if you don't want your eyes to bleed by having to read the actual language spec)...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Reserved_Words
The following are keywords and may not be used as variables,
functions, methods, or object identifiers, because ECMAScript
specifies special behavior for them:
I'm not quite sure what the point is you want to make, so the only answer I can give is: Yes, it's ok to use reserved words as property names.
(However two small remarks: foo["class"] is ok, not foo[class]. And any way you should be using form.elements["xyz"] and not form.xyz to access an element named xyz.)
Yes, it can be used.
Just small remark, if you use YUI compressor you have to put property name which is equal to one of js reserved words in quotes.
For example, this won't compress
var a = { case : "foo"}; // syntax error, "invalid property id"
a.for = "bar"; // syntax error, "missing name after . operator"
This will do
var a = { "case" : "foo"}; //OK
a["for"] = "bar"; //OK
Here is Online JavaScript/CSS Compression Using YUI Compressor where this can be tested.
Yes, in most browsers (including IE9+)
There's actually an entry in the Kangax compatibility table for "Reserved words as property names"
http://kangax.github.io/compat-table/es5/#test-Object/array_literal_extensions_Reserved_words_as_property_names

correct function parameters designation

Every time i pass some parameters to a JavasScript or jQuery functon, i use some random letters. What are the correct letters for the corresponding variable types?
function(o){} for example is for a object. But what are the other letters? Do someone have a list of those?
I advise you not to assign names according to types but according to the data that the variable contain. If you pass an object that contains the configuration for a function call the variable configuration if you pass a variable that contains a name call it name and so on. In this way the code is more readable and understandable.
Any letter will do, there is no such thing as a standard for using letters as parameters.
However, using letters for parameters is bad practise, because a letter does not describe what the parameter is intended for.
Consider this example:
function ShowBusyCursor(s) {
//...
}
If you look at the function header, you cannot guess what the parameter s stands for. But if you change the code to this:
function ShowBusyCursor(cursorIsDisplayed) {
//...
}
The parameter cursorIsDisplayed is a lot more developer-friendly and tells you it's a boolean that can be set to true to display the cursor. If you used s, you would have to look into the code to figure that out.
Here is a good list of letters I could think of:
o - object
a - array
s - string
d - date
n - number
r - regexp
b - boolean
But seriously, jokes apart, I think you might be mixing up the packed/minified source with the actual source that developers write. For example, this little function looked like this originally:
function myFunction(personName) {
this.name = personName;
}
But after minifying, it becomes:
function myFunction(a){this.name=a}
packer is one such utility by Dean Edwards that will minify your Javascript. Play with your source code at this website and see the compressed output. Check the Shrink variables option on the right to see how parameters and other variables get renamed.
This however shouldn't affect how you write your code at all. Be it Javascript, or any other language, all identifiers - variables, function names, class names, etc. should be named after what they represent or do rather than obscure shorthands.
Re-iterating what mck89 said, it's better to go with explanatory variable names rather than just a letter for the type. What if you have more than one parameter of the same time, do you start appending numbers?
I have often seen explanatory variable names which include the type, for instance sFirstName would be a string denoted by the "s", bForce would be a boolean, oConfig would be an object and nSubTotal would be a number.
This is a variation of Hungarian notation, and I'd advise against using single-letter variable names. What if you need to pass in 2 of any one data type? Like others have said, it also doesn't represent the meaning of the variable very well. I think this is much better:
function foo(sFirstName, sLastName)
{
alert("Hi, my name is " + sFirstName + " " + sLastName);
}

Categories