That alone is a concern, because any junior programmer getting an introduction through React is going to get a twisted understanding of the language itself.
That alone is a concern, because any junior programmer getting an introduction through React is going to get a twisted understanding of the language itself.
But in terms of the industry-standard practices/ecosystem, it is a terrible first language if you want to gain a generalized understanding. What you describe here is extremely true; I've seen it in practice:
> any junior programmer getting an introduction through React is going to get a twisted understanding of the language itself
I've talked with otherwise very capable JS devs who have built impressive things with multiple frameworks, but don't have a good handle on fundamental concepts like the difference between the two kinds of function syntax (they may have only ever used one), how Promises behave outside of a narrow subset of situations, what NodeJS actually is (despite having used it), or even the difference between passing by reference vs value.
Many of these frameworks create such a narrow lens into the language itself, add what are effectively (sometimes literally) their own DSLs on top, sprinkle in some magical behavior, and when all is said and done you hardly end up using JS at all.
Obviously there's a benefit from doing things this way or it wouldn't have happened. But I can't help but think the technologies that work well for industry are having a detrimental effect on a generation of new programmers.
You can only pass by value in JS so maybe that's why. It is a bit confusing because of how objects work that it feels like you are passing by reference. You are passing reference as the value.
I once talked to someone with >5 years front-end experience, including some team-lead experience, who thought the difference between == and === was that === compares objects deeply. That is very, dangerously wrong. The only way I can imagine he got by for so long with that misconception is that he'd always used ImmutableJS.
It's still pass by value, you are passing the reference of the object as a value.
let a = { foo: "bar" }
let b = { foo: "bar" }
console.log(a === b) // false
and this: let a = { foo: "bar" }
let b = a
b.foo = "blah"
console.log(a.foo) // "blah"
This is the kind of misunderstanding that causes insidious bugs.The distinction is that, if JS truly was pass-by-reference for objects, you could change what the reference was pointing to. But you can't.
I agree with you that objects/references are a stumbling block for new programmers in JS. You have to understand how these things work but there's no explicit concept of a reference, which means it can be tricky to learn.
That's only true if you're passing the pointer by reference. That's different from passing the object itself by reference.
I did just look up the C++ semantics and learned something: technically reference-arguments don't have to be implemented by the compiler as pointers, though in practice they mostly are. So in that sense it's technically more correct to say that JS works with object pointers and not references. But we're really getting quite deep into the weeds at that point.
https://stackoverflow.com/questions/5893873/pass-by-referenc...
That's how all mainstream languages with a GC work, Java, C#, Ruby and Python, it's not particular to JS. And this why why languages like Clojure are nice to work with.
but it also isn't important
It's important if you really want to know why your examples work they way they do.
We're specifically talking about new programmers who haven't used any of those languages, and who are being reared in the JavaScript ecosystem where certain patterns reign that obscure this language behavior. That's what the original discussion was about.
> It's important if you really want to know why your examples work they way they do.
It's really not. Pass-by-reference and pass-a-pointer-by-value are subtly different concepts even in the C++ world, and using terminology that involves the word "pointer" opens up a whole other can of stuff that needs explaining.
A variable stores reference to the original object and when you pass it to a function, it passes the actual reference as the value.
I think the last part you mentioned is actually confusing in js because lack of clear guidance.
isXyz, Xyz.isXyz, Object.is, and other ways are used in practice to do the same thing but they all have different behavior which trips people.
Passing by reference has a well defined meaning in computer language terminology. It means passing something that references the variable outside the function. Something you can't do in JavaScript
void someFunc(ref int v) {
v = 456;
}
var foo = 123;
someFunc(foo);
write(foo); // output 456
Above we are not passing 123 (the value of foo) into someFumc, we are passing a reference to foo. This is what pass by reference means.same if foo was reference to an object
void someFunc(ref Object v) {
v = someOtherObject;
}
var foo = someObject;
someFunc(foo);
// foo now refers to someOtherObject
In this impossible in JavaScript. It does not have the concept of pass by reference. It only has pass by value function someFunc(v) {
v = someOtherObject;
}
var foo = someObject;
someFunc(foo);
// foo still refers to someObject
Above the value of foo, which is a reference to someObject, that value is assigned to v in someFunc. v's value is set to reference someOtherObject. foo's value is still someObject as there is no way to "pass by reference" in JavaScriptHaving spent my career in languages with pass by reference it feels unnatural not to have it. I suspect if I started with JS this wouldn't be such a problem.
function someFunc(v) {
v.myvar = 456;
v = someOtherObject;
}
var foo = someObject;
foo.myvar = 123;
someFunc(foo);
// foo still refers to someObject
// foo.myvar is 456
Banning our team from passing objects around except in specific, discussed, cases got rid of lots of difficult to track down bugs.Passing a reference to an object is not "pass by reference". Your example works the same in Java and C# and probably Swift and many other languages. But you aren't "passing by reference". "pass by reference" specifically means passing a reference to the variable, not the variable's value. Javascript always passes the value of the variable, it has no ability to pass a variable by reference.
And so much of the industry everywhere is about “do X to get Y result” and any further reflection is kindof a luxury. How does your package manager work? Part of the point is not to know, which works until it doesn’t. So we all get trained into basically a culture of issuing commands in a manner not too different from the machines we ask to do the work, and developing a model of what’s going on is either bonus study or earned by running your hands over the sharp edges when you’re bucked onto the unhappy path.
Which definitely happens outside of JS. I suspect it happens more inside because JS functions as maybe the biggest funnel into the field.
There is more than 2 now. :)
You have the keyword function, you have
const myFunc = (param) => { //body }
and then you have the various types that can occur within a class, which can have a little bit different behavior based on which syntax you use.
Fun times!
And remember, arrow functions within a class have a this, but arrow functions outside of a class don't have a this!
This is not correct. Arrow functions have the `this` value of the outer context.
I recommend this article to understand `this`: https://web.dev/javascript-this/
You are correct, I wasn't clear. I was describing the end effect of free floating arrow functions VS an arrow function declared within a class.
When free floating, trying to access 'this' can (will) result in unexpected behavior, when inside a class arrow functions operate exactly as people expect a class member function to operate in other languages. (In contrast to having to otherwise bind JS functions to 'this')
In both cases the arrow function is acting the same way, but most intro to JS lessons don't explain it.
Indeed the way it was originally explained to me is that "arrow functions in classes auto bind to this" which is hilariously inaccurate, but the end effect is as if that was happening.
That said, vanilla JS can be hard like this as well, especially as "solved" legacy issues still regularly crop up in tutorials and code-bases. Many times I remember helping newer folks with challenges they found online that seemed to them like they were testing hard computer science problems, but were more just trivia to navigate some bad design decisions of JS (eg gotcha problems on "this" / binding, IFFE, hoisting, async/promises/callbacks, to name a few)