I've been searching around Stack Overflow, and the web in general, for a decent explanation of something I'm seeing in some legacy JavaScript. So far I haven't had much luck, so I've decided to take the extreme measure of actually posting a question. :-)
The code isn't super old, but it pre-dates my involvement in the project and (of course) the developer who originally created it left before I got here.
So here we go:
Normally when I'm looking # code that creates JavaScript 'classes' I see something like:
var SomeClass = function() { ..stuff.. }
...other code...
var objSomeClass = new SomeClass();
Also familiar is the JavaScript literal:
var someLiteral = { ..stuff.. }
...other code...
var someResult = someLiteral.someFunction();
What I'm seeing in the legacy code appears to be a combination of the two styles, and I've never seen anyone do this before. So what we've got is:
var someLiteral = { ..stuff.. }
...other code...
var objSomeLiteral = new someLiteral();
Also, in the same code are declarations like this:
function doStuff() { ..stuff.. }
...other code...
var objDoStuff = new doStuff();
Again, I've never seen anyone write code quite like this before.
Is this semantically incorrect code, or is there some valid reason for doing it this way that I'm just not aware of? Which is always possible, I make no claims to JavaScript expertise at this point.
The code definitely works, but if it's not 'good' code then I'm going to want to re-write it. Cuz I'm just anal like that. :-)
Thanks!
new <Object> is a syntax error. That's simply not valid JavaScript. The operand of new has to be a function.
Also using functions as constructors like you showed in your "class" construct example is a very common practice.
Related
here is my React hooks code:
function calc_c({a,b}){
//some long calculation that is based on a,b
}
function MyComponent(params){
var a=calc_a(params)
var a=calc_b(params)
var c=React.useMemo(()=>calc_c({a,b},[a,b])
}
my question: how to I find out which of the params in [a,b] changed and caused the calls to calc_c
edit: I ended up using a generic version of skyboyer excelent answer:
export function useChanged(name,value){
function print_it(){
console.log('changed',name)
}
React.useMemo(print_it,[value])
}
It depends whether you ask for debugging purposes or you'd like to rely on that in your code(e.g. "if A is changed then return B, otherwise C")
For both cases, there is no simple way to achieve. But work arounds would differ.
Assume you just want to figure out why this is recalculated. Then just put bazillion
useEffect(() => {
console.log("a is changed");
}, [a])
One per each dependency. Yes, boring and repetitive. But the simplest approach is, the less you should actually worry about additionally. Or take a look if useWhatChaged works to you(if there are literally dozen variables in dependency list).
Another thing, if you would like to make check(but why?) in your regular(not in temporary code for debugging purposes I mean). Then you might use usePrevious or write something similar.
Some of my code got a review comment saying something like "move const outside the function to avoid redeclaration". This was a normal function component, something like this:
export default function someComponent() {
const someString = 'A string';
///...
}
I was confused about the idea of this causing a redeclaration, because it does not, I know that the record that holds the variables and constants belong to the scope, so it's not exactly that.
But then i remembered that typescript does not allows you to have a const inside a class, not sure about the reason or is this is related. But then ts added the readonly modifier in ts v2, so the confusion remains.
Should const be outside function components, or not?
I would love to know more opinions.
There are 2 sides to the coin. Firstly, in terms of clean code and readability, I strongly prefer local declarations like in your example. I would love using more nested functions as well.
However, in JavaScript, every time the function executes, the local definitions will be redeclared, even if they are constants or functions. So it's a trade-off. If the function is called many times, this becomes an overhead.
I think it would not be hard for a compiler like TypeScript's tsc or some other pre-processor to extract those definitions at compile time to have best of both worlds. But it's likely that they do not do this to remain fully compatible. I am not aware of such tools but would be interested if there are some.
I usually need the element's scope which is something like $(element).scope() or angular.element(..).scope()
But now I have the opposite problem - I have a scope, and I need to find which element generated it.
How can I find out from the developers' console which element it is?
Why do I need this?
I am working on someone else's code, fixing a bug.
I am still trying to figure out some stuff, but some of the code is quite hard to follow. Very generic and a lot of copy-paste, so searches don't always help.
There's a lot of ng-includes and directives that use the parent scope.
There's a view calling a service somehow - it is unclear how yet..
I do have a reference to a scope, which is different from the one in the view that triggers the function.
So if I find the element from which that scope came from, it could sort out the relation between them etc.. At least give me some lead.
Obviously some refactoring and best practices are required in the future, but I have to focus on this bug first.
I know of nothing 'out-of-the-box', but every $scope variable has a unique $id property; and in addition, every element that has a $scope gets marked with the 'ng-scope' class. So something along the lines of the following VERY UGLY METHOD! may help (I'm assuming you have jQuery; otherwise substitute angular's jqueryLite methods):
function findById(id) {
var els = $('.ng-scope');
for (var i=0; i<els.length; i++) {
if ($(els[i]).scope().$id===id) {
return els[i];
}
}
return null;
}
And if this is actually helpful, then I feel your debugging pain.
I have an angular 1.4 project on typescript, the project is getting bigger and bigger and our team is really tired of interfaces that we have declared (so that all objects are typed, in comparison to any)
I'm asking if this is a good idea or not? I chose typescript because I wanted to have a typed project, should I drop the interfaces or not?
You can get by without using interfaces and going with any, but in the long term you are probably going to regret it. If your team is sick of the interfaces you've created, I would put time in fixing those instead of abandoning them. There is a significant argument around if typed languages reduce the number of errors found in code. Personally, I think they do.
What I've found with typed languages is that it helps remove stupid mistakes we all make, and this clears up our time to focus on actual logic problems in code. Not everyone agrees with me on this, but I will always pick a type language over a non typed one, especially if the team is used to dealing with languages like Java or C#.
Interfaces can be very helpful if used properly.
If you are just doing this....
IFoo { ... }
Foo implements IFoo { ... }
Then they will not help as much as they do in other typed languages (C#/Java). Because the type checking in TypeScript is dependent upon the properties on the object and NOT on the declared type. This is because you can simply write this...
MyCtrl (foo: Foo) { ... }
//instead of
MyCtrl {foo: IFoo) { ... }
This will not hinder unit testing in any way since as stated above the type checking is based upon properties and not declarations.
There are cases when interfaces can be quite helpful, for instance a common use case is when defining an object as a parameter...
doSomething (options: ISomethingOptions) { ... }
There is no harm in creating interfaces for everything, you just need to determine what level of typing works best for your team.
I am mostly a C++ developer, recently I am writing iPhone applications.
The memory management on iPhone is OK to me, due to resource limitation, it's encouraged to use reference counters rather than deep copy.
One annoying thing is I have to manage the reference counters by myself: alloc means counter = 1; retain means counter++, release means counter--
I wish to write a shared_ptr like class for Cocoa Touch, so I rarely have to manually manipulate the reference counters by myself.
I doubt if there's any existing code for that, and I'd like to hear some advices, today is the 5th day since I started to learn objective c
Thanks.
As long as you learn the memory management rules first, there is no real problem with shared_ptr - it can help you in C++ contexts but doesn't let the ownership questions magically disappear.
shared_ptr supports a custom deallocator so the following:
#interface A : NSObject
- (void)f;
#end
#implementation A
- (void)dealloc { NSLog(#"bye"); [super dealloc]; }
- (void)f { NSLog(#"moo"); }
#end
void my_dealloc(id p) {
[p release];
}
// ...
{
shared_ptr<A> p([[A alloc] init], my_dealloc);
[p.get() f];
}
... outputs:
moo
bye
... as expected.
If you want you can hide the deallocator from the user using a helper function, e.g.:
template<class T> shared_ptr<T> make_objc_ptr(T* t) {
return shared_ptr<T>(t, my_dealloc);
}
shared_ptr<A> p = make_objc_ptr<A>([[A alloc] init]);
You forgot case 4
[4] you need to pass a pointer to an object out of a method as the return value.
This is where you need -autorelease.
I suggest you read the memory management rules and write some real code before you attempt this little project so that you can get a feel of how memory management is supposed to work.
Automatic reference counting, coming in iOS 5, will effectively make any pointer to an objective-c object act like a smart pointer. Retain/release calls will be synthesized by the compiler on assign and deallocation, unless you explicitly declare a reference to be weak, in which case they'll be automatically zeroed out when the object is deallocated.
My advice is to wait a couple of months for that. You might be able to put together something similar in the meantime, but I'd recommend against it. For one thing, it'll be ugly. Example:
smart_ptr<id> array = make_smart_ptr( [NSMutableArray array] );
NSUInteger count = [array count]; // won't work.
count = [array.get() count]; // works, but yuck.
[array.get() setArray: anotherArray.get()]; // even more yuck.
Also, if your headers are full of c++ classes, you'll have to compile your entire project in objective-c++, which may cause you problems as objective-c++ isn't 100% compatible with objective-c code, and not all third-party frameworks will work properly with it. And forget about sharing your code with anyone else.
It might be an interesting excercise to make something like this work, but you won't want to actually use it. And watch out for the temptation to recreate your favourite bits of C++ in Objective-C. The languages are very different, and you could spend a lot of time doing that, which is time not spent learning all the great stuff you can do in Objective-C that you can't do in C++.
Resource management in Cocoa can be tricky: some API calls automatically retain a reference and some don't, some return an autoreleased object, some a retained object. By shielding this in a shared_ptr class, you'll more likely to make mistakes. My advice is to first take the "normal" Cocoa route until you're fairly experienced.
Have you looked into [object autorelease]? Perhaps that would make things a bit easier.