Javascript左侧的可选链接

时间:2019-11-15 14:22:13

标签: javascript typescript

是否可以在Javascript分配=的左侧使用optional chaining运算符?

const building = {}
building?.floor?.apartment?.number = 3; // Is this possible?

4 个答案:

答案 0 :(得分:1)

不可能,抱歉。

为了得到一个规范的答案:MDN文档对此没有明确说明,但是您可以阅读proposal's README in GitHub以获得更多信息。 says

  

尽管以下内容有一些用例,但不支持以下内容:参见Issue #18进行讨论:

     
      
  • 可选的属性分配:a?.b = c
  •   

链接的问题中有评论1

  

好的,似乎在这个线程中有一个大致的约定,就是不要在第一次迭代中进行写操作。

2

  

我们还在TC39上讨论了这个问题,委员会似乎对添加此功能并不那么感兴趣。

所以我想这不太可能很快发生。

希望有所帮助;祝你好运!

答案 1 :(得分:1)

我正在研究这一点,遗憾的是,正如其他评论者已经指出的那样,在撰写本文时,通过可选链进行的赋值似乎在打字稿中是不可能的,并且确实会产生解析器警告:

<块引用>

赋值表达式的左侧可能不是可选的属性访问。

当尝试类似的事情时:

class A{
    b?: string;
}

var a = new A();
a?.b = "foo";

但由于可选赋值有时很有用,因此仍然使用像这样的单行 if 查询的老式方法:

class A{
    b?: string;
}

try{a.b = "foo0"} // throws TypeError
catch(e){console.log(e.toString())} // a is undefined

if(a) a.b = "foo1"; // skips
console.log(a); // a is undefined

var a: any;
if(a) a.b = "foo2"; // skips
console.log(a); // a is undefined

a = null;
if(a) a.b = "foo3"; // skips
console.log(a); // a is null

a = undefined;
if(a) a.b = "foo4"; // skips
console.log(a); // a is undefined

a = new A();
if(a) a.b = "foo5"; // runs
console.log(a); // a is A: {"b": "foo5"}

if(null) console.log("bar0"); // skips
if(undefined) console.log("bar1"); // skips
if({}) console.log("bar2"); // runs
if({something: "there"}) console.log("bar3"); // runs
if([]) console.log("bar4"); // runs
if(["not empty"]) console.log("bar5"); // runs

为了演示一个实际可行的示例,这里有一个 kotlin 代码段:

class A{
    var b: B? = null;
    var title: String? = null;
    override fun toString():String = "Instance of class A with title: ${this.title} and b of value: ${this.b.toString()}";
}

class B{
    var title: String? = null;
    override fun toString():String = "Instance of class B with title: ${this.title}";
}

fun main() {
    var a:A? = null;
    println(a); // null
    
    try{a!!.title = "foo0"} catch(e:Exception){println(e)} // NPE
    
    a?.title = "foo1";
    println(a); // null
    
    a = A();
    println(a); // Instance of class A with title: null and b of value: null
    
    a?.title = "foo2";
    println(a); // Instance of class A with title: foo2 and b of value: null
    
    try{a!!.b!!.title = "bar0"} catch(e:Exception){println(e)} // NPE
    
    a?.b?.title = "bar1";
    println(a); // Instance of class A with title: foo2 and b of value: null
    
    a?.b = B();
    println(a); // Instance of class A with title: foo2 and b of value: Instance of class B with title: null
    
    a?.b?.title = "bar2";
    println(a); // Instance of class A with title: foo2 and b of value: Instance of class B with title: bar2

    a?.b?.let{it.title = "bar3"}
    println(a); // Instance of class A with title: foo2 and b of value: Instance of class B with title: bar3
}

现在我不是在争论一种语言比另一种更好,而是目的和哲学需要不同的设计选择,并决定最终任何编程或脚本语言的工具的最终形状。 同时也有点恼火,我不能在打字稿中为可选链赋值。

编辑:我使用了这些 Playground 网站,这些网站对测试这些东西很有用:

答案 2 :(得分:0)

我已经在Chrome Canary上尝试过此操作(由于browser compatibility),但无法正常工作: enter image description here

答案 3 :(得分:0)

否,这是不可能的。 documentation明确指出

  

可选的链接运算符?。允许读取的值   属性位于连接对象链的深处,没有   必须明确验证链中的每个参考文献都是   有效。