Skip to content

ES6

class 单例模式

js
class A {
  constructor(param) {
    if (A.instance) {
      return A.instance
    }
    this.param = param
    A.instance = this
  }
}

const a = new A('a')
const b = new A('b')

console.log(a === b) // true

在上述代码中,A 类的构造函数检查是否已经存在一个实例。如果不存在,它将当前实例设置为 A.instance,然后返回该实例。这确保了无论多少次尝试实例化 A 类,都只会返回同一个实例。

这种实现方式利用了 JavaScript 的类的构造函数只会在第一次实例化时被调用的特性,从而保证只有一个实例被创建。

可选链操作符

可选链操作符 ?. 允许读取位于连接对象链深处的属性值,而不必明确验证链中的每个引用是否有效。

?. 操作符功能类似于 . 操作符,不同之处在于,在引用为空(null 或者 undefined)的情况下不会引起错误,该表达式返回的值是 undefined

js
const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

console.log(adventurer.dog); // undefined

console.log(adventurer.dog.name); // Uncaught TypeError: Cannot read properties of undefined

const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined

console.log(adventurer.someNonExistentMethod?.());
// expected output: undefined

空值合并运算符

空值合并运算符是一个逻辑操作符,当左侧的操作数为 undefined 或者 null 时,返回其右侧操作数,否则返回左侧操作数。

与逻辑或操作符不同,逻辑或操作符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到预料之外的行为,如 0 || 2 会返回 2

js
const foo = undefined ?? 'default string'
console.log(foo) // default string

const baz = 0 ?? 2
console.log(baz) // 0

const bar = 0 || 2
console.log(bar) // 2

更多例子:

js
const nullValue = null;
const emptyText = ""; // 空字符串,是一个假值,Boolean("") === false
const someNumber = 42;

const valA = nullValue ?? "valA 的默认值";
const valB = emptyText ?? "valB 的默认值";
const valC = someNumber ?? 0;

console.log(valA); // "valA 的默认值"
console.log(valB); // ""(空字符串虽然是假值,但不是 null 或者 undefined)
console.log(valC); // 42
js
let myText = ''; // An empty string (which is also a falsy value)

let notFalsyText = myText || 'Hello world';
console.log(notFalsyText); // Hello world

let preservingFalsy = myText ?? 'Hi neighborhood';
console.log(preservingFalsy); // '' (as myText is neither undefined nor null)

实际应用:

js
// 输入框非空判断
if (value !== null && value !== undefined && value !== '') {
  // ...
}

// 使用空值合并运算符
if ((value ?? '') !== '') {
  // ..
}