JavaScript is constantly being upgraded and iterated, and there are more and more new features to make our code simple and interesting to write, this article will introduce 5 new features, let’s study them together.
1. Use “Object.hasOwn” instead of the “in” operator
Sometimes, we want to know if a property exists on an object, we usually use the “in” operator or “obj.hasOwnProperty”, but they both have their own drawbacks.
in
The “in” operator will return true if the specified property is located in the object or its prototype chain.
1
2
3
4
5
6
7
8
|
const Person = function (age) {
this.age = age
}
Person.prototype.name = 'fatfish'
const p1 = new Person(24)
console.log('age' in p1) // true
console.log('name' in p1) // true 注意这里
|
obj.hasOwnProperty
The hasOwnProperty
method returns a boolean value indicating whether the object ownProperty has a corresponding value in it (properties in the prototype chain are not read).
1
2
3
4
5
6
7
8
|
const Person = function (age) {
this.age = age
}
Person.prototype.name = 'fatfish'
const p1 = new Person(24)
console.log(p1.hasOwnProperty('age')) // true
console.log(p1.hasOwnProperty('name')) // fasle 注意这里
|
obj.hasOwnProperty
can already filter out properties in the prototype chain, but in some cases it is still not safe.
1
2
|
Object.create(null).hasOwnProperty('name')
// Uncaught TypeError: Object.create(...).hasOwnProperty is not a function
|
Object.hasOwn
Don’t worry, we can use Object.hasOwn to avoid these two problems, which is more convenient and safer than the “obj.hasOwnProperty” method.
1
2
3
4
5
6
|
let object = { age: 24 }
Object.hasOwn(object, 'age') // true
let object2 = Object.create({ age: 24 })
Object.hasOwn(object2, 'age') // false
let object3 = Object.create(null)
Object.hasOwn(object3, 'age') // false
|
2. Declaring Private Attributes with #
Previously, we usually use _
to denote private properties, but it is not reliable and can still be modified externally.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class Person {
constructor (name) {
this._money = 1
this.name = name
}
get money () {
return this._money
}
set money (money) {
this._money = money
}
showMoney () {
console.log(this._money)
}
}
const p1 = new Person('fatfish')
console.log(p1.money) // 1
console.log(p1._money) // 1
p1._money = 2 // 依旧可以从外部修改_money属性,所以这种做法并不安全
console.log(p1.money) // 2
console.log(p1._money) // 2
|
Use “#” for truly private attributes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class Person {
#money=1
constructor (name) {
this.name = name
}
get money () {
return this.#money
}
set money (money) {
this.#money = money
}
showMoney () {
console.log(this.#money)
}
}
const p1 = new Person('fatfish')
console.log(p1.money) // 1
// p1.#money = 2 // 没法从外部直接修改
p1.money = 2
console.log(p1.money) // 2
console.log(p1.#money) // Uncaught SyntaxError: Private field '#money' must be declared in an enclosing class
|
3. very useful “number separator”
See the example directly.
1
2
3
4
5
|
const sixBillion = 6000000000
// ❌ 难以阅读
const sixBillion2 = 6000_000_000
// ✅ 更加易于阅读
console.log(sixBillion2) // 6000000000
|
Of course it can also be used in computational expressions.
1
|
const sum = 1000 + 6000_000_000 // 6000001000
|
4. Use “?.” Simplifying “&&” and ternary operators
These examples must be very familiar to you, is there a way to simplify them?
1
2
3
4
|
const obj = null
console.log(obj && obj.name)
const $title = document.querySelector('.title')
const title = $title ? title.innerText : undefined
|
“?.”
1
2
3
4
|
const obj = null
console.log(obj?.name)
const $title = document.querySelector('.title')
const title = $title?.innerText
|
Tips
?. The general usage of.
- obj?.prop object property
- obj?. [expr] object property
- func?. (… .args) Execute function
5. Using “BigInt” for large numbers
It is not safe to calculate numbers in JS that exceed Number.MAX_SAFE_INTEGER
.
Example:
1
2
3
|
Math.pow(2, 53) === Math.pow(2, 53) + 1 // true
// Math.pow(2, 53) => 9007199254740992
// Math.pow(2, 53) + 1 => 9007199254740992
|
This problem can be completely avoided by using “BigInt”.
1
|
BigInt(Math.pow(2, 53)) === BigInt(Math.pow(2, 53)) + BigInt(1) // false
|