垃圾代码.jpg

static public function get_instance() {
  return Config::$instance === null ? Config::$instance = Config::create() : Config::$instance;
}

我就好奇了,我记得在三元表达式下进行赋值,应该是不返回东西的啊(JS 难道不是返回 undefined 么)

一般遇到这种场景,我经常会这样单独进行一次赋值:

function test(obj){
  if(!obj) obj = {a: 2};
  return obj;
}

尤其是这个 if 看着就感觉很霎眼。

我按照 Eric 的代码截图也写了个片段试了试,确实不返回。可这段代码我其实写错了,因为这里是当 obj 存在的时候设置成 {a: 1}

function a(obj){
  return obj ? obj = {a: 1} : obj;
}
a(); // undefined

根据他的写法,完全模拟一个出来,结果是成的,为什么呢?

let obj = null;

function a(){
  return obj === null ? obj = {a: 1} : obj;
}
a(); // {a: 1}

这其实就是因为 obj = {a: 1} 除了进行了赋值,也返回了 {a: 1} 这个值,因为三元表达式本身就是 if else 的缩写版,因此返回第一个条件的值也就自然变成了 {a: 1} 了。

如果你把它换成一个没有 return 的函数,这里返回确实就是 undefined 了。

let obj = null;

function b(){
  obj = {a: 1};
}

function a(){
  return obj === null ? b() : obj;
}
a(); // undefined
console.log(obj); // {a: 1}

又换了一个写法,不按照 Eric 的 === null 去判断,这次就有问题了,如果 objnull 就不管用了。这又是为什么呢?

let obj = null;

function c(){
  return obj ? obj = {c: 1} : obj;
}
c(); // null

这是因为 obj 在为 null 的时候,obj === true 返回 false,obj === false 也是 false

奇怪的是,如果 objString / Number / Array / Object 的任意对象,都会视作为 true。这就是很迷的地方。如果是 String,空字符串 ""false,有内容的都算 true

那遇到 null 咋办呢?最简单的办法,就是直接给对象取反,不然你只能把判断条件改为 undefinednull

function d(obj){
  return !obj ? {a: 2} : obj;
}
d(); // {a: 2}
d(null); // {a: 2}
d({a: 3}); // {a: 3}

@Innei 的补充,更简写的方式,甚至还不会出现 null 的问题

let obj = null; // 如果改成 {a: 4},下面就是 {a: 4} 了

function e(){
  return obj ??= {a: 3};
}
e(); // {a: 3}

参考

sec-assignment-operators