3

我有下面的代碼,我試圖在一個參數的幫助下執行一個函數。上面的參數告訴Javascript來在陣列上/串使得其指示執行的操作(例如ps陣列並且如果id參數爲0 properties字符串,as陣列和attributes串如果id不爲0):數組賦值中的引用錯誤(左手邊分配)

var properties = "apple=fruit"; 
var attributes = "carrot=vegetable banana=fruit cherry=fruit fruit"; 
var ps = []; 
var as = []; 

function getpsas(id) 
    { 
    (id === 0 ? ps : as) = (id === 0 ? properties : attributes).split(" ").map 
    (
    function(element) 
     { 
     var eqlpos = element.lastIndexOf("="); 
     return {name: element.substr(0, eqlpos), type: element.substr(eqlpos + 1)}; 
     } 
    ).filter 
     (
     function(element) 
     { 
     return (/^(vegetable|fruit)$/.test(element.type)); 
     } 
    ); 
    } 

getpsas(0); 
getpsas(1); 

console.log(ps); 
console.log(as); 

Fiddle這裏。它會在(id === 0 ? ps : as) =部分引發「Uncaught ReferenceError:賦值中無效的左手邊」。如果我從=左側刪除括號,它將起作用,除了它執行僅適用於後一個陣列(又名as)而不是前者(又名ps)的功能。

我知道我在這裏做錯了什麼,錯過了一個符號/一對括號或其他東西。我已經檢查了operator precedence in Javascript,關於同一事件的其他問題,但都表明它應該起作用,因爲操作員(我認爲)是正確的,例如,條件的===,轉讓的簡單的=等。最令我困惑的是三元運算符內的其他引用(本示例的右邊部分,我的代碼的其他部分)工作。

那麼......這個有什麼問題呢?

回答

3

您不能在作業的左側使用? :。三元運算符表達式的值始終爲的值,而不是的引用;編程語言人們通常使用的r值l值。您只能分配到的l值,但不能生成l值? :

「l」和「r」代表「左」和「右」並且與賦值運算符有關。當然,並非所有的語言都從右向左進行分配;音樂編程語言「查克」是一個反例。

如果你將值分配給一個對象的屬性,你可以做這樣的事情:

someObject[foo == bar ? "x" : "y"] = whatever(); 

這是因爲? :是一個子表達式是左手側的判定的一部分分配。這沒關係,因爲外部[ ]表達式返回l值

+0

我不得不承認,這是最好的答案,只是因爲它正好說明發生了什麼,爲什麼我的做法是不正確的。我解決了這個問題,但沒有使用「對象」(嚴格來說),而是通過將等式的右邊部分分配給「虛擬數組」(名爲_temp_),然後使_if(id === 0){ps = temp;} else {as = temp} _在我的函數結尾處。如果您提供了適用於我的特定代碼的簡單解決方案,那麼您的答案將會非常完美,但即便如此,這也是最好的答案。謝謝。必須刪除並重新發布我更正的評論,因爲我無法編輯它。 –

2

表達式(id === 0 ? ps : as)返回psas的值。如果你想分配something的變量做這樣的事情:

if (0 === id) ps = something; 
else as = something; 

另一種方式是有條件通過計算成員訪問環繞psas一個對象,並設置任一成員:

const obj = { 
    ps: [], 
    as: [], 
} 

obj[0 === id ? 'ps' : 'as'] = something; 
+0

好的答案,解決方案導向,但它缺乏解釋爲什麼會發生這種情況(Pointy的答案並不缺乏)。我不得不標記他的答案,因爲我實際上明白我錯在哪裏。儘管如此,我還是給了你一個讚賞 - 謝謝。 –

1

你可以用一個數組和computed property names做一個destructuring assignment

function getpsas(id) { 
 
    [ps, as] = Object.assign([ps, as], { 
 
     [id]: [properties, attributes][id] 
 
      .split(" ") 
 
      .map(function (element) { var eqlpos = element.lastIndexOf("="); return { name: element.substr(0, eqlpos), type: element.substr(eqlpos + 1) }; }) 
 
      .filter(element => /^(vegetable|fruit)$/.test(element.type)) 
 
    }); 
 
} 
 

 
var properties = "apple=fruit", 
 
    attributes = "carrot=vegetable banana=fruit cherry=fruit fruit", 
 
    ps = [], 
 
    as = []; 
 

 
getpsas(0); 
 
getpsas(1); 
 

 
console.log(ps); 
 
console.log(as);
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

感謝您提供完全適合我的代碼的解決方案。就像傑弗裏的回答一樣,這無疑是有幫助的,但並不能解釋我錯在哪裏。雖然提出了你的意見。 –

+0

這只是一個答案,什麼是可能的。你的問題已經被[Pointy](https://www.filecrypt.cc/Container/D24940861A.html)所描述,不需要重複。 –

+0

確實。你可以檢查我的評論給Pointy,看看我如何解決它,而不使用額外的對象(臨時數組除外)。 –