As I know, in JavaScript there is no good solution to make private member. Solution described here is not efficient, because private members become parts of objects, not prototypes, and hence require more memory.
So, I decided just use Python practice - to mark private stuff with leading underscore, letting other to know that makred property or method is not intended to be used from outside.
But there is well-known code quality tool - JSLint, and it suggests to not use leading or trailing underscores.
What is the rationale behind this? Is this just code style suggestion or underscores can lead to more serious problems? If its just code style convention in JS community, how strong it is?
JSLint is a good tool, but it expresses opinions about coding practices that are in the style of its authors. Read about what those preferences are here. There is no harm in the JavaScript parser in using a leading underscore/underbar, the tool is programmed to see this as a bad convention and warn you against using it. If using leading underscores is your preference and it makes sense, use them.
If you don't want to see the warnings in JSLint when using identifiers that begin with an underscore/underbar there is a setting within JSLint to hide these from you. Wrap the code that you don't want to be evaluated like this example and you won't see the warnings:
/*jslint nomen: true */
var _gaq = {};
/*jslint nomen: false */
This is true if you're having code evaluated from a file, but if you're on the JSLint website there is an option to "Tolerate... dangling _ in identifiers" that removes the warning as well.
Please note that doing this may cause issues in how JSHint parses the file. Take a look at this link showing JSLint vs JSHint in relation to that flag. But if you're going to go by the JSLint standard mixing JSHint can cause a bit of confusion.
Private variables don't exist in JavaScript without using closures, but it's not a pattern needed for every project execution. If you want to know more about closures in JavaScript check out Ben Nadel's wonderful blog post and NetTuts+
It's just a code style suggestion.
You can use JSHint instead and set-up it following the code style in your project/company.
As to me there's nothing bad if you mark private members in this way. The main rule should be to follow the unified convention in the whole project. If this makes your code more readable and maintainable, you're free to follow own convention for current project.
Underscore prefix can be use as convention. But is just a convention.
If the private member is a property of the object's instance the only way is to declare a variable in constructor. The properties of an object are never registred in prototype. If you store a property in proto, his value was share with all other instance.
It work like statics in POO.
The prototype is only use to solve an undefined property in the instance.
Exemple:
function O(){}
O.prototype.name = "John";
var o = new O;
// o look like that :
// {
// __proto__: { name: "John"}
// }
console.log(o.name); // write "John"
o.name = "Tom";
// now :
// {
// name: "Tom",
// __poto__: { name: "John" }
// }
console.log(o.name); // write "Tom"
The definition of name on instance not override the prototype value. It only store in the instance before the proto value in cascade resolution.
Sorry for my bad english.
Related
I'm trying to read a JSON array. Every time i try to read the array/value by passing JSON object key like this-
json[key]
It shows a Eslint error-
[eslint] Generic Object Injection Sink (security/detect-object-injection)
I understand its a security warning because the key may not exists. But how do i resolve this warning? Is there any easier way to read the Json object. My plan is to pass the "key" to the function and read the json based on the key.
You are searching for an ES lint error fix:
Here is the syntax for it
json [`${key}`]
Example:
const obj = {
eventName: 'Music event',
landingPic: 'landing.jpg',
eventPic0: 'pic0.jpg',
eventPic1: 'pic1.jpg',
eventPic2: 'pic2.jpg',
eventPic3: 'pic3.jpg',
artist: 'Elie'
};
// array of keys which need to be read
const arrayOfKey = ['landingPic', 'eventPic0', 'eventPic1', 'eventPic2', 'eventPic3'];
// let's read the value by a key in array
arrayOfKey.forEach( key => {
const value = obj[`${key}`];
console.log(value);
});
There is a good answer here. In general this rule is for paranoiac and the article to which everyone appeal is a mislead. So the best answer, I would say is to turn this rule off, if you can for sure.
And another answer in the comments refers to eslint contributor answer that this rule is pretty false positive prone and more for human to audit a codebase(warning level) rather then give an error in a CI. So I would say you can totally ignore this rule or turn it off.
If you cannot turn it off or ignore, you can disable the eslint for line with comment that it's a false positive or use some interpolation as mentioned in other answers.
And finally, in order to destroy any doubts, the answer from creator of the rule:
"I'm the original author of this rule - for a bit of context, it was originally written as an assistive tool for manual code reviews, to be
used with the eslint plugin for VS Code. I would recommend disabling
it for other use cases, as it's just going to be far too noisy."
Unsure why, but typecasting the access parameter silences the error. Guessing this has something to do with sanitation being able to prevent pollution.
const myThing = myObj[String(key)]
const myThing = myObj[key as string]
What its trying to say is that using this notation:
You are able to modify even prototype properties of the object which is considered dangerous
By being able to modify everything, you are also able to modify the constructor (method/function) so it may be injected and then exploited.
The subject is described analytically here, providing a simple example:
https://web.archive.org/web/20150430062816/https://blog.liftsecurity.io/2015/01/15/the-dangers-of-square-bracket-notation
Kotlin enables the extension of existing types. For example we can do this:
fun String.replaceSpaces(): String {
return this.replace(' ', '_')
}
val formatted = str.replaceSpaces()
However in JavaScript this is an antipattern.
Does Kotlin sidestep the issues that this causes in Javascript?
No this is not an antipattern. In js its an antipattern because js is dynamic and therefore changing a prototype changes how code works at runtime making it an antipattern. This is also extremely dangerous based on how the in operator works and based on the fact that you can rewrite everything, so changing a prototype can affect code somewhere on your page:
Number.prototype.toString = function(){
return "bullshit";
};
alert(""+12);
In kotlin this is not the case as kotlin is static, and all references are built at compile time. Additionally, you cant overwrite existing methods so its not dangerous at all.
You cannot compare a prototyped language like JS with Kotlin. All extensions are resolved statically and do not modify the extended type ("receiver"). This is really important and invalidates your worry. Please have a look at the documentation to learn more about the things happening with extensions in the background (compiler).
In my opinion, you need to be cautious with extensions though. Don't allow each and every developer in a Kotlin project to add new extensions to random types. I think the project must define certain rules handling the process of defining new functions/properties on existing types, because otherwise it can get hard to read foreign code. Also there should be firm arranged locations where to put those extensions.
No it is not good. It is very bad that Kotlin allows extensions of existing types.
With extensions there is no reason at all to create a class hierarchy or even create a new class definition for that matter.
Kotlin creators might as well have just used erlang instead of going to the trouble of creating extensions.
Extensions mean that you can no longer rely on a class definition to be constant. Imagine all the time people are going to spend just finding a developer's "creative" extensions let alone debugging them.
You should have compiled this example and seen the generated code. Everything would become clear:
function replaceSpaces($receiver) {
return replace($receiver, 32, 95);
}
function foo(str) {
var formatted = replaceSpaces(str);
}
There's no monkey patching at all! Extension functions are just a syntactic sugar in Kotlin. It's just another way of passing first argument to a static function.
Several languages had this already. The problem with JavaScript is the way it works, as stated in the answer of the link.
JavaScript has a couple way of overriding property. A library could have very well defined a override, but the other one override it again. The function get called from both library, all hell breaks loose.
It’s more a type system and visibility issue in my opinion.
The main arguments against extending prototypes in JavaScript are twofold:
The methods you add might have the same name as methods added by some library used in the same application, but have different behaviour.
Future version of JavaScript/ECMAScript itself might include a method with the same name as the one you're adding, but with different behaviour.
In JavaScript, both of these scenarios will lead to the wrong version of a method being called at runtime, unexpectedly, resulting in a runtime crash or unexpected runtime behaviour.
In Kotlin, most scenarios akin to this will result in a compile-time error or at least a warning, and so the perils encountered when extending types in JavaScript are mostly avoided in Kotlin. However, there is still some slight scope to encounter similar runtime bugs in rare cases.
To illustrate this, let's write some examples of code where conflicting implementations of a method exist, and see what happens.
Scenario 1: Two libraries provide an extension method with the same signature
Suppose we have this code, in Main.kt and Library1.kt respectively:
import library1.*
import library2.*
fun main() {
listOf(99, 101, 103, 104).printOddVals()
}
package library1
fun List<Int>.printOddVals() {
for (x in this) {
if (x % 2 != 0) {
println(x)
}
}
}
So the library1 package defines a printOddVals method that prints the odd values in a list, and main() uses it. Now suppose that in library2, we introduce a conflicting printOddVals method, that prints the values with odd indices:
package library2
fun List<Int>.printOddVals() {
for ((i, x) in this.withIndex()) {
if (i % 2 != 0) {
println(x)
}
}
}
In the equivalent scenario in JavaScript, this would probably cause a runtime bug. In Kotlin, it merely leads to a compile-time error:
Main.kt:5:31: error: overload resolution ambiguity:
public fun List<Int>.printOddVals(): Unit defined in library1 in file Library1.kt
public fun List<Int>.printOddVals(): Unit defined in library2 in file Library2.kt
listOf(99, 101, 103, 104).printOddVals()
^
IntelliJ IDEA will also tell you how to fix the issue - by introducing an import alias:
Do that, and we get this code, with the ambiguity about which printOddVals we want to call resolved:
import library1.*
import library2.*
import library2.printOddVals as printOddVals1
fun main() {
listOf(99, 101, 103, 104).printOddVals1()
}
Scenario 2: A library introduces a member function that shadows an extension method you already wrote
Suppose we have the following files:
package library1
class Cow {
fun chewCud() {}
}
import library1.*
fun Cow.moo() {
println("MOOOOOOO!")
}
fun main() {
val cow = Cow()
cow.moo()
}
So Cow.moo is initially an extension method we wrote. But then we update library1, and then new version has a moo member function:
package library1
class Cow {
fun chewCud() {}
fun moo() { println("moo") }
}
Now, because member functions are preferred to extension functions when resolving method calls, our extension function is not used when we call cow.moo() in main(), and then library's new member function is used instead. This is a change in runtime behaviour, and potentially a bug if the library's new moo() implementation isn't an adequate substitute for the extension function we'd written before. However, the saving grace is that this at least produces a compiler warning:
Main.kt:3:9: warning: extension is shadowed by a member: public final fun moo(): Unit
fun Cow.moo() {
^
Scenario 3: A library introduces a member function that shadows an extension method you already wrote, and doesn't produce a compiler warning
Once we add inheritance (or interface implementation) into the mix, we can contrive a situation similar to the one above where an extension function we were previously using gets partially shadowed by a member function after a library update, causing changes in runtime behaviour, and no compiler warning occurs.
This time, suppose we have these files:
import library1.*
fun Animal.talk() {
println("Hello there! I am a " + this::class.simpleName)
}
fun main() {
val cow = Cow()
val sheep = Sheep()
cow.talk()
sheep.talk()
}
package library1
interface Animal
class Cow : Animal
class Sheep : Animal
At first, when we run our main() function, our extension function gets used for both cow.talk() and sheep.talk():
Why hello there. I am a Cow.
Why hello there. I am a Sheep.
. But suppose we add a talk member to Cow:
package library1
interface Animal
class Cow : Animal {
fun talk() {
println("moo")
}
}
class Sheep : Animal
Now if we run our program, the member function on Cow gets preferred to the extension method, and our program's behaviour has been changed - all with no compiler errors or warnings:
moo
Why hello there. I am a Sheep.
So although extension functions are mostly safe in Kotlin, there's still a tiny bit of potential to run into the same pitfalls as in JavaScript.
Is this theoretical danger sufficient to mean that extensions should be used sparingly, or perhaps avoided entirely? Not according to the official Coding Conventions, which take the view that extensions are great and you should use them lots:
Extension functions
Use extension functions liberally. Every time you have a function that works primarily on an object, consider making it an extension function accepting that object as a receiver. To minimize API pollution, restrict the visibility of extension functions as much as it makes sense. As necessary, use local extension functions, member extension functions, or top-level extension functions with private visibility.
You are, of course, free to form your own view!
I'm looking at Addy Osmani's gist for a publication/subscription pattern here:
https://github.com/addyosmani/pubsubz/blob/master/pubsubz.js
He surfaces his object as a global like this:
;(function ( window, doc, undef ) {
var topics = {},
subUid = -1,
pubsubz ={};
....
getPubSubz = function(){
return pubsubz;
};
window.pubsubz = getPubSubz();
What is the value of creating that getPubSubz function? Wouldn't it be more straightforward to simply write:
window.pubsubz = pubsubz;
Yes, in this case, because getPubSubz is only called in one place, immediately after declaring it, it could safely be inlined.
It's hard to say exactly what the author had in mind, but in a growing code base there may be some value to having a "getter" function which could be modified if the act of getting the pubsubz object required more advanced logic.
It absolutely would be.
There are only two potential reasons why a getter would be used in this case:
There was previously some additional code inside the getter (logging, perhaps)
Addy Osmani's just following good practice*, and including a getter—even adding the opportunity to add additonal code in the future.
Through the power of GitHub, we can actually eliminate option one, as the getter was added in its current state—so I think we can conclusively say that it's just a matter of good practice here.
*as jantimon alludes to in the comments below, this isn't particularly advantageous in most cases (including this one) and this code does not necessarily need to followed as an example.
I'm sure someone is going to shout at me for asking this question, but here goes: in Javascript, what is the best strategy for coping with the fact that the properties of objects are case-sensitive? If I create an object with a property called FavouriteDrink, but then I later start referring to it as favouriteDrink then I could end up in a mess.
I don't want a big library here, but is there any way to define the object so that FavouriteDrink is defined somewhere, and where in Visual Studio 2012 some intellisense will help me choose the correct property name if I can somehow contextualise the object I'm dealing with? It is only properties I'm pondering here.
Thanks.
It doesn't work this way
if i look at your your code and see :
FavouriteDrink() {}
the first thing will popup in my mind is this is a constructor function not just a normal function
and by looking at this following one
favouriteDrink() {}
i would tell that this is a normal function and i can't use it as a constructor - can't be called with new
Here is some other examples
first_name // variable
FIRST_NAME // uppercase variables shouldn't change
_first_name // local variable not intended to be used out of its scope
var FIRSTNAME = {} // name space
it’s a good idea to follow a convention as to how the words will be separated
see this Code Conventions for the JavaScript Programming Language
For the other part of your question i'm using VS 2012 and i installed JSEnhancements
and i can see all my object element
JavaScript shares the following conventions with Java and ActionScript 3.
ALL_UPPERCASE
Use this as the variable name when you define a constant, or a value that should never change.
For example, myObject.NUM_TIMES_CLICKED = 2 would be a poor candidate for a constant because it is likely to change. However, myObject.APPLE_FRENCH_SPELLING = 'pomme' would be appropriate here.
firstWordLowercaseAndTheRestAllUppercase
Use this when you are defining anything that is not a constant or a class. You would use this for most things, for example, myObject.numTimesClicked, myObject.myFunction(), myObject.returnString.
AllWordsCapitalized
Use this when you are defining a function that defines a "class," generally any function you would call with the syntax myObject.myClassInstance = new MyClass(). Notice how myClassInstance is in camel-case because it is an instance of the class. However, MyClass is all caps because it is meant to be invoked with new.
You would define the class initially like this: myObject.MyClass = function(){};
WebStorm and Sublime Text are great tools that offer the code intelligence you're looking for.
WebStorm does this out of the box, but my personal preference is Sublime Text with the SublimeCodeIntel plugin.
That being said, it's probably best for you to be using naming conventions:
UpperCamelCase is for classes
ALL_CAPS_SNAKE_CASE is for constants
lowerCamelCase is used for everything else
I've recently tested UglifyJS and YUI Compressor and noticed something odd.
Both minifiers don't seem to change the names of object properties, only the names of variables and functions.
for instance if I have the following code:
var objName = {first:2, second:4};
alert(objName.first + " " + objName.second);
the names first and second remain unchanged in the minified version.
Why is that?
Since in javascript a new scope is created in a function, you can scope your code in an immediately invoked function.
// scoped
(function() {
var objName = {first:2, second:4};
alert(objName.first + " " + objName.second);
})();
Then using Google's Closure Compiler, if you turn on the "Advanced" optimization it will see that the properties are only used locally, and will obfuscate them.
// result
var a={a:2,b:4};alert(a.a+" "+a.b);
It's because it doesn't know where the object is going to be used. It could be used externally by other code and you wouldn't want your other code to have to change whenever you obfuscate it.
Edit So basically, it's like that to prevent obfuscation from breaking external/internal references to properties that may not be possible to figure out while obfuscating.
Since there are no well defined scoping rules around objects in JavaScript it's impossible to obfuscate the names in a way that is guaranteed to be correct.
For example, if you had the following function:
function f() {
return { first: 'foo', second: 'bar' };
}
In order to obfuscate the property names you would have to nail down all the places that f is called from. Since functions are first-class in JavaScript they can be assigned and passed around in arbitrary ways making it impossible to pin down where f is referenced without actually running the program.
Additionally, JavaScript doesn't have any way for you to specify intent around what's public API and what isn't. Even if the minimizer could reliably determine where the function is called from in the code you give it, there would be no way for it to make the same changes to code that it hasn't seen.
I guess that's because the minifiers would break the object properties. Consider this:
function getProp(ob,name) {
return ob[name];
}
var objName = {first: 2, second: 4};
var prop = getProp(objName, "second");
There's no way for the minifier to know the string literal "second" being an object property. The minified code could look like this then:
function a(b,c){return b[c]}var d={p1:2,p2:4};var e=a(d,"second")
Broken now.
The latest release of uglify (today) has object property mangling, see v2.4.19. It also supports reserved files for excluding both object properties and variables that you don't want mangled. Check it out.
The only public tool so far to obfuscate property and function names (afaik) is the Closure Compiler's Advanced mode. There are a lot of limitations and restrictions, but the end result is generally worth it.
As a passing note: the Dojo Toolkit is compatible (with some minor modifications) with the Closure Compiler in Advanced mode -- arguably the only large-scale public JavaScript library that can be fully obfuscated. So if you are looking at obfuscation to protect your IP, you should look into using Dojo for the task.
http://dojo-toolkit.33424.n3.nabble.com/file/n2636749/Using_the_Dojo_Toolkit_with_the_Closure_Compiler.pdf?by-user=t
Stephen
What about doing something like:
// scoped
(function() {
var objName = {first:2, second:4};
var vA = 'first';
var vB = 'second';
alert(objName[vA] + " " + objName[vB]);
})();
Once objName.first and/or objName.second are referenced enough times, this technique will start to save characters. I can't think of any reason that wouldn't work, but I can't find any minifiers that do it.