Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

9 mistakes for Python programmers when learning JavaScript #70

Open
AllanChain opened this issue Feb 7, 2020 · 0 comments
Open

9 mistakes for Python programmers when learning JavaScript #70

AllanChain opened this issue Feb 7, 2020 · 0 comments
Labels
blog: programming @post This is a blog post tag: javascript |178272204-7e20ff98-56d1-457d-842f-70a4ecd17e0f.png

Comments

@AllanChain
Copy link
Owner

AllanChain commented Feb 7, 2020

View Post on Blog

Although Python and JavaScript share a lot of similarities and are both learning from each other, there are still some important differences to notice.


The new Operator

You can simply create an instance of a class by ClassName(...) in Python. But in JavaScript you need the new operator. It can be easily forgotten!

See also https://stackoverflow.com/q/1646698/8810271, https://stackoverflow.com/q/383402/8810271

But why sometimes it still works when I forget new? For example:

> b = new Date()
2020-02-08T05:20:14.069Z
> c = Date()
'Sat Feb 08 2020 13:20:19 GMT+0800 (GMT+08:00)'

As the second link shows, there is a trick:

function foo() {
   // if user accidentally omits the new keyword, this will 
   // silently correct the problem...
   if ( !(this instanceof foo) )
      return new foo();
   // constructor logic follows...
}

However, you must use new if you are using class:

> class Bar {
... constructor() {
..... if ( !(this instanceof Bar) ) return new Bar()
..... this.foo = 1
..... }
... }
undefined
> Bar()
Thrown:
TypeError: Class constructor Bar cannot be invoked without 'new'
> new Bar()
Bar { foo: 1 }

Element in Array or Key in Object / dict

In Python, we have:

>>> 3 in [1, 2, 3]
True
>>> 3 in {1: 2, 3: 4}
True

However, in JavaScript:

> 3 in [1, 2, 3]
false
> 3 in {1: 2, 3: 4}
true

That's because in JavaScript, even Array act like a Object:

> let a = [1, 2, 3]
undefined
> a.b = 5
5
> a
[ 1, 2, 3, b: 5 ]

So, JS just always detects keys. To determine whether an element in Array, you should do:

> a.includes(3)
true

Weird map / Are they Different?

>>> list(map(int, ['1', '2', '3']))
[1, 2, 3]
>>> list(map(lambda s: int(s), ['1', '2', '3']))
[1, 2, 3]
> ['1', '2', '3'].map(parseInt)
[ 1, NaN, NaN ]
> ['1', '2', '3'].map(s => parseInt(s))
[ 1, 2, 3 ]
> [1, 2, 3].map(console.log)
1 0 [ 1, 2, 3 ]
2 1 [ 1, 2, 3 ]
3 2 [ 1, 2, 3 ]
[ undefined, undefined, undefined ]
> [1, 2, 3].map(s => console.log(s))
1
2
3
[ undefined, undefined, undefined ]
> [1, 2, 3].forEach(console.log)
1 0 [ 1, 2, 3 ]
2 1 [ 1, 2, 3 ]
3 2 [ 1, 2, 3 ]
undefined

mapwill pass 3 parameters: value, index, and the Array itself, as shown in [1, 2, 3].map(console.log)

And, passing too many arguments will not cause error:

> const g = s => console.log(s)
undefined
> g(1, 2, 3)
1
undefined

And as for parseInt, there is a second parameter (see below). That's why parseInt and s => parseInt(s) are different.

parseInt v.s. int

parseInt(string [, radix])

Parameters

string

The value to parse. If this argument is not a string, then it is converted to one using the ToString abstract operation. Leading whitespace in this argument is ignored.

radix Optional

An integer between 2 and 36 that represents the radix (the base in mathematical numeral systems) of the string. Be careful—this does not default to 10!

If radix is undefined, 0, or unspecified, JavaScript assumes the following:

  1. If the input string begins with "0x" or "0X" (a zero, followed by lowercase or uppercase X), radix is assumed to be 16 and the rest of the string is parsed as a hexidecimal number.
  2. If the input string begins with "0" (a zero), radix is assumed to be 8 (octal) or 10 (decimal). Exactly which radix is chosen is implementation-dependent. ECMAScript 5 clarifies that 10 (decimal) should be used, but not all browsers support this yet. For this reason, always specify a radix when using parseInt.
  3. If the input string begins with any other value, the radix is 10 (decimal).

If the first character cannot be converted to a number, parseInt returns NaN unless the radix is bigger than 10.

Well, that makes sense. And I'm going to specify a radix when using parseInt.

And note that Python is more friendly:

class int(object)
 |  int([x]) -> integer
 |  int(x, base=10) -> integer
 |
 |  Convert a number or string to an integer, or return 0 if no arguments
 |  are given.  If x is a number, return x.__int__().  For floating point
 |  numbers, this truncates towards zero.
 |
 |  If x is not a number or if base is given, then x must be a string,
 |  bytes, or bytearray instance representing an integer literal in the
 |  given base.  The literal can be preceded by '+' or '-' and be surrounded
 |  by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
 |  Base 0 means to interpret the base from the string as an integer literal.
 |  >>> int('0b100', base=0)
 |  4

Dead Variable

Based on https://stackoverflow.com/a/54980674/8810271

> let a = nothing
Thrown:
ReferenceError: nothing is not defined
> let a = 1
Thrown:
SyntaxError: Identifier 'a' has already been declared
> a = 1
Thrown:
ReferenceError: a is not defined

Once you have a typo when using let in console (such as forgetting new), the variable name will never come back. That's because variable initialization did not complete successfully, and you can't re-declare a variable that's already been declared.

Worse still, you cannot delete the variable declared using let, const or var. Only things like "global variable" can be deleted. See also https://stackoverflow.com/q/1596782/8810271

You have to reinvent a good variable name, or reopen the console.

Sure Sorted?

> [2, 1].sort()
[ 1, 2 ]
> [8, 10].sort()
[ 10, 8 ]

No, JS sort is just String sorting:

The sort() method sorts the elements of an array in place and returns the sorted array. The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.

And if you want number sorting, write:

> [8, 10, 6, 19].sort((a, b) => a - b)
[ 6, 8, 10, 19 ]

How do you split?

Even though expression is the same, the answer does not.

>>> 'asdf adsf ak g'.split(' ', 1)
['asdf', 'adsf ak g']
> 'asdf adsf ak g'.split(' ', 1)
["asdf"]

Hmm, I'd better split, slice and join..

Mutable Default Parameter?

Javascript seems not affected.

> const f = (a=[]) => { a.push(1); return a }
undefined
> f()
[ 1 ]
> f()
[ 1 ]
>>> def f(a=[]):
...     a.append(1)
...     return a
... 
>>> f()
[1]
>>> f()
[1, 1]

Beware of Method / Function Names

Some methods / functions achieve similar, if not the same, effect, but with different names. They are so similar that I often get confused.

>>> 'abc'.startswith('a')
True
>>> ''.join(['a', 'b', 'c'])
'abc'
>>> 'abc'.index('a')
0
> 'abc'.startsWith('a')
true
> ['a', 'b', 'c'].join('')
'abc'
> 'abc'.indexOf('a')
0
@AllanChain AllanChain changed the title From Python to JavaScript | AC's Blog From Python to JavaScript Jun 24, 2020
@AllanChain AllanChain added the tag: javascript |178272204-7e20ff98-56d1-457d-842f-70a4ecd17e0f.png label Jun 24, 2020
@AllanChain AllanChain added the @post This is a blog post label Jul 3, 2020
@AllanChain AllanChain changed the title From Python to JavaScript Top 9 Mistakes Python Programmers Make When Learning JavaScript Aug 31, 2022
@AllanChain AllanChain changed the title Top 9 Mistakes Python Programmers Make When Learning JavaScript Top 9 mistakes for Python programmers when learning JavaScript Aug 31, 2022
@AllanChain AllanChain changed the title Top 9 mistakes for Python programmers when learning JavaScript 9 mistakes for Python programmers when learning JavaScript Aug 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blog: programming @post This is a blog post tag: javascript |178272204-7e20ff98-56d1-457d-842f-70a4ecd17e0f.png
Projects
None yet
Development

No branches or pull requests

1 participant