I was once asked by a student why we write:
parseInt(something)
something.toLowerCase()
that is, why one has the variable as a parameter, while the other is applied to the variable.
I explained that while toLowerCase is a method of string objects, parseInt wasn’t designed that way. OK, so it’s window.parseInt, but that just makes it a method of a different object.
But it struck me as an inconsistency — why are some string or other functions not methods of their corresponding objects?
The question is why? Is there a technical reason why parseInt and other functions are not methods, or is that just a historical quirk?
In general, Javascript was designed in a hurry, so questioning each individual design decision isn't always a productive use of your time.
Having said that, for parseInt in particular, the reason is simple to explain: it accepts pretty much any arbitrary type, like:
parseInt(undefined) // NaN
Since you cannot implement undefined.parseInt(), the only way to do it is to implement it as a static function.
As of ECMAScript 2015, parseInt has been mirrored in Number.parseInt, where it arguably makes more sense than on window. For backwards compatibility window.parseInt continues to exist though.
In this specific case it makes sense with respect to encapsulation.
Consider parseInt() - it is taking a value of an unknown type from an unknown location and extracting an integer value from it. Which object are you going to have it a method of? All of them?
String.toUpperCase() should only take a string as input (else something which may be cast as a string) and will return a string. This is well encapsulated within a small subset of cases, and since values are not strongly typed it seems logical to not have it as a global function.
As for the rest of JavaScript I have no idea nor do I have insight into the real reason it was done this way, but for these specific examples it appears to me to be a reasonable design decision.
The development progress of the JavaScript language is quite fast in recent years. With that in mind, a lot of things are still in the API due to backward compatibility - historical reasons as you said. Although I can't say that's the only reason.
In JavaScript, you can approach a problem not just with Object oriented paradigm (where methods of objects usually shares a common state). Another, functional approach can be applied quite easily without getting into too much trouble with JavaScript language.
JavaScript gives great power to its users with many possibilities of approaching a problem. There is a saying: "With Great Power Comes Great Responsibility".
Related
I did a search on this topic, but I do not know what keyword to search for so I post this question.
I wondered why the name reduce was chosen in javascript even though the name has been used, such as fold or accumulate, which is more traditional and meaningful(this is my personal opinion).
I've spoken about this topic with someone close to me (one of the people I know who has been dealing with Javascript for a long time and who has also worked with functional languages like Scheme, Racket, and Clojure). He cautiously speculated that this might be an effect of Python.
If you have any traditional context that I do not know, or someone you know about the background of this name, I would be very grateful if you could answer.
If you look at https://en.wikipedia.org/wiki/Fold_(higher-order_function)#Folds_in_various_languages, you can see that the most common names for this operation are fold, reduce, and inject. reduce is by no means an unusual name. In particular, reduce is used in Perl (which JavaScript copied many features from), and Perl probably got it from Lisp (like many other features). The earliest reference I can find is REDUCE in Common Lisp (which was developed in the 1980s and standardized in 1994).
What naming conventions are people using for variables that hold JSON-serializable objects? We'd like the name of the variable to remind us to only store information in the object that can be serialized into JSON without losing information. Applications include HTTP sessions, non-searchable database columns, data logging, and serializing restorable application state.
The obvious contenders, at least from the perspective of someone programming in Javascript for node.js, seem to fall short:
prefixJSON - JSON is actually a serialization syntax, so this
would properly be a string in JSON format, not an object
prefixInfo - info is often used in node.js for any kind of map,
including ones that take functions and instances of ES6 classes.
prefixMap - Same issue as the info suffix
prefixData - Doesn't really suggest a constraint on the type
The best I can do is prefixJSONInfo, prefixJSONData, or prefixJSONObject, but I was hoping for something more succinct and readable. The prefix may be lengthy and descriptive too.
This question mainly applies to programming languages that support variant-type variables, such as Javascript. These variables are meant to hold a mishmash, but the programmer needs to be reminded to limit the types of values that are thrown into the mishmash.
In this case, it seems that a specific acronym might serve a good purpose.
JSONSerializable
written:
JSS or Jss
Examples:
prefixJss
customerDataJss
sessionInfoJss
Or maybe even:
JSONSerializableObject
prefixJSO
prefixJso
My $0.02. This might be more opinion based, as I don't think there are any globally accepted standards for these things. There are best practices, such as you mentioned (like short but descriptive). It's up to the developer or team to determine which short and descriptive versions they like (team preference).
Trust me tho, I understand how difficult naming things is sometimes. :)
As an exercise, I've been working on replicating this game. In case it becomes inaccessible, the premise of the game is to take a quote that's been scrambled by swapping pairs of letters (eg replace A with M and vice versa), and unscramble it to its original arrangement.
As I'm studying this game, I realize it's almost trivial to extract the solution from the source - there are any number of breakpoints you can place to access it. I've been trying to come up with a way to obscure the string in a way that it isn't immediately accessible, and the only thing I can think of is some kind of native obscuring function before the quote even has a chance to land in a variable. Something like this:
var litmus, quotes = [
"String One",
"String Two",
....
"String n",
];
litmus = obscureString(quotes[Math.floor(Math.random()*(n-1))]);
This way the user can't summon up the raw quote, or even the random integer that was used - they're gone by the time the breakpoint hits.
My question is this: is there any kind of native function that would fit the role of obscureString() in the above example, even loosely? I'm aware JavaScript doesn't have any native encryption/hash methods, and any libraries that provide that functionality just provide a chance to drop a breakpoint. Thus, I'm hoping someone here can come up with a creative way to natively obscure a string, if it's even possible in JS.
Been crunching on it for a while, and I found a very makeshift solution.
The only native (read: non-user-corruptible) transformation/hash function I was able to find was window.btoa. It does exactly what I need, in letting me obscure a string before the user ever has a chance to get their hands on it. The problem, however, is that it has a counterpart window.atob, whose only purpose is to reverse the process.
To solve that, I was able to neutralize window.atob with the following line of code, essentially making window.btoa a one-way trip:
window.atob = function(f){ return f; };
Don't make a habit of this.
This is horrific practice, and I feel dirty for writing it. It's passable in this case because my application is small, self-contained, and won't ever need to rely on that function elsewhere - but I can't in good conscience recommend this as a general solution. Many browsers won't even let you override native functions in the first place.
Just wanted to post the answer in case someone found themselves in a similar situation needing a similar answer - this may be the closest we can get to a one-way native hash function for now.
Enumerating the keys of javascript objects replays the keys in the order of insertion:
> for (key in {'z':1,'a':1,'b'}) { console.log(key); }
z
a
b
This is not part of the standard, but is widely implemented (as discussed here):
ECMA-262 does not specify enumeration order. The de facto standard is to match
insertion order, which V8 also does, but with one exception:
V8 gives no guarantees on the enumeration order for array indices (i.e., a property
name that can be parsed as a 32-bit unsigned integer).
Is it acceptable practice to rely on this behavior when constructing Node.js libraries?
Absolutely not! It's not a matter of style so much as a matter of correctness.
If you depend on this "de facto" standard your code might fail on an ECMA-262 5th Ed. compliant interpreter because that spec does not specify the enumeration order. Moreover, the V8 engine might change its behavior in the future, say in the interest of performance, e.g.
Definitely do not rely on the order of the keys. If the standard doesn't specify an order, then implementations are free to do as they please. Hash tables often underlie objects like these, and you have no way of knowing when one might be used. Javascript has many implementations, and they are all competing to be the fastest. Key order will vary between implementations, if not now, then in the future.
No. Rely on the ECMAScript standard, or you'll have to argue with the developers about whether a "de facto standard" exists like the people on that bug.
It's not advised to rely on it naively.
You should also do your best to stick to the spec/standard.
However there are often cases where the spec or standard limits what you can do. I'm not sure in programming I've encountered many implementations that deviate or extend the specification often for reasons such as the specification doesn't cater to everything.
Sometime people using specifics of an implementation might have test cases for that, though it's hard to make a reliable test case for beys being in order. It most succeed by accident or rather it's difficult behavior to reliably produce.
If you do rely on an implementation specific then you must document that. If your project requires portability (code to run on other people's setups out of your control and you want maximum compatibility) then in this case it's not a good idea to rely on an implementation specific such as key order.
Where you do have full control of the implementation being used then it's entirely up to you which implementation specifics you use while keeping in mind you may be forced to cater to portability due to the common need or desire to upgrade implementation.
The best form of documentation for cases like this is inline, in the code itself, often with the intention of at least making it easy to identify areas to be changed should you switch from an implementation guaranteeing order to one not doing so.
You can make up the format you like but it can be something like...
/** #portability: insertion_ordered_keys */
for(let key in object) console.log();
You might even wrap such cases up in code:
forEachKeyInOrderOfInsertion(object, console.log)
Again, likely something less overly verbose but enough to identify cases dependent on that.
For where your implementation guarantees key order you're just trans late that to the same as the original for.
You can use a JS function for that with platform detection, templating like CPP, transpiling, etc. You might also want to wrap the object creation and to be very careful about things crossing boundaries. If something loses order before reaching you (like JSON decode of input from a client over the network) then you'll likely not have a solution to that solely withing your library, this can even be just if someone else is calling your library.
Though you'll likely not need those, just make cases where you do something that might break later as a minimum and document that potential exists.
An obvious exception to that is if the implementation guarantees consistency. In that case you will probably be wasting your time decorating everything if it's not really a variability and is already documented via the implementation. The implementation often is a spec or has its own, you can choose to stick to that rather than a more generalised spec.
Ultimately in each case you'll need to make a judgement call, you may also choose to take a chance. As long as you're fully aware of the potential problems including the potential of wasting time avoiding problems you wont necessarily actually have, that is you know all the stakes and have considered your circumstances, then it's up to you what to do. There's no "should" or "shouldn't", it's case specific.
If you're making node.js public libraries or libraries to be widely distributed beyond the scope of your control then I'd say it's not good to rely on implementation specifics. Instead at least have a disclaimer with the release notes that the library is only catering to your stack and that if people want to use it for others then can fix and put in a pull request. Otherwise if not documented, it should be fixed.
When should object literals be used in javascript, sometimes I get confused I am trying to apply oop concepts and pattern to the language. I am trying to not just use procedural programming concepts because I know the language has amazing capabilities.
Object literals are most commonly used as:
a type of associative array; and
a way of passing many arguments to a function.
The second is particularly important and common in libraries like jQuery.
That's how they're commonly used. As for when you should use them, that's a difficult question to answer because it's a bit like asking when should arrays be used. Object literals are a tool. They're a means to an end not an end in itself.
The subtext of your post suggests you're trying to imprint some non-Javascript concepts onto Javascript. I see this a lot (particularly where people try and make everything OO in PHP as the most egregious example). Javascript has its own strengths and weaknesses. Play to those. Don't try to make it something it isn't.
One common mistake is that people confuse OO with Classical language design. You really don't want to be thinking in terms of classes when it comes to javascript, you want to be thinking in terms of functions, duck typing, and prototypes.
This may seem obvious but Javascript object literals are also commonly used for data exchange with other systems. JSON after all is just a subset of Javascript object literal syntax.
Object literals also play an important role in JSON. Though it is important to note JSON is language independent.