【问题标题】:Optional chaining on the left side in JavascriptJavascript左侧的可选链接
【发布时间】:2021-05-07 19:52:29
【问题描述】:

是否可以在 JavaScript 中的赋值 = 的左侧使用 optional chaining 运算符?

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

【问题讨论】:

  • 不,不可能。
  • 我很惊讶阅读该文档并测试该代码并没有告诉您答案。
  • 从文档中看不清楚。文档说“允许阅读...”,这并不意味着不允许分配。
  • 但是,我想分配,我该怎么做? passwordErr?.confirmation_password = "测试"

标签: javascript typescript


【解决方案1】:

这是不可能的,抱歉。

为了一个规范的答案:MDN 文档没有明确说明这一点,但您可以阅读proposal's README in GitHub 了解更多信息。它says

虽然有一些用例,但不支持以下内容;请参阅Issue #18 进行讨论:

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

在链接的问题中是 cmets 1:

好的,在这个线程中似乎有一个粗略的协议,在第一次迭代中不做写案例。

2:

我们在 TC39 上也讨论过这个问题,委员会似乎对添加这个功能不太感兴趣。

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

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

【讨论】:

    【解决方案2】:

    我正在研究这个问题,遗憾的是,正如其他评论者已经指出的那样,在撰写本文时,通过可选链接的分配似乎在打字稿中是不可能的,并且确实会给您带来解析器警告:

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

    当尝试类似的事情时:

    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 sn-p:

    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 网站,它们对测试这些东西很有用:

    【讨论】:

      【解决方案3】:

      我在 Chrome Canary 上尝试过这个(因为 browser compatibility),但没有成功:

      【讨论】:

      • 你不能,任何地方。它不是规范的一部分。
      【解决方案4】:

      不,这是不可能的。 documentation 明确说明

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

      【讨论】:

        猜你喜欢
        • 2015-05-27
        • 1970-01-01
        • 2020-12-13
        • 2016-05-11
        • 1970-01-01
        • 1970-01-01
        • 2014-03-29
        • 2014-11-28
        相关资源
        最近更新 更多