IT TIP

쉼표 연산자는 언제 유용합니까?

itqueen 2020. 10. 22. 23:47
반응형

쉼표 연산자는 언제 유용합니까?


식 ( ) 의 "쉼표 연산자"에 대한 질문 ,과 이에 대한 MDN 문서읽었 지만 유용한 시나리오를 생각할 수 없습니다.

그렇다면 쉼표 연산자는 언제 유용할까요?


다음은 직접 작성하지 않기 때문에 유용하지 않을 수 있지만 축소자는 쉼표 연산자를 사용하여 코드를 축소 할 수 있습니다. 예를 들면 :

if(x){foo();return bar()}else{return 1}

될 것입니다 :

return x?(foo(),bar()):1

? :(어느 정도) 콤마 연산자는 두 문장 한 문장으로 기입 할 수 있기 때문에 운전자는 현재 이용 될 수있다.

이것은 이다 (-> 24 여기 바이트 39)는 몇 가지 참신한 압축 할 수 있다는 점에서 유용하다.


나는 쉼표 var a, b표현식 내에 존재하지 않기 때문에 쉼표 연산자 아니라는 사실을 강조하고 싶습니다 . 쉼표는 명령문 에서 특별한 의미를 갖습니다 . 식에서 두 변수를 참조 할 것이고, 평가에 대한 경우하지 않다 .var a, bbvar a, b


쉼표 연산자를 사용하면 하나의 표현식이 예상되는 위치에 여러 표현식을 넣을 수 있습니다. 쉼표로 구분 된 여러 표현식의 결과 값은 마지막 쉼표로 구분 된 표현식의 값이됩니다.

두 개 이상의 표현식이 예상되는 상황이 많지 않고 쉼표 연산자를 사용하는 것보다 코드를 작성하는 데 덜 혼란스러운 방법이 없기 때문에 개인적으로 자주 사용하지 않습니다. 한 가지 흥미로운 가능성은 for두 개 이상의 변수를 증분시키려는 경우 루프 끝에 있습니다.

// j is initialized to some other value
// as the for loop executes both i and j are incremented
// because the comma operator allows two statements to be put in place of one
for (var i = 0; i < items.len; i++, j++) {
    // loop code here that operates on items[i] 
    // and sometimes uses j to access a different array
}

여기서는 i++, j++하나의 표현이 허용되는 곳에 놓을 수 있음을 수 있습니다. 이 특별한 경우에는 여러 표현이 부작용에 사용되므로 복합 표현이 마지막 표현의 값을 취하는 것은 중요하지 않지만 실제로 문제가 될 수있는 다른 경우가 있습니다.


쉼표 연산자는 Javascript로 기능 코드를 작성할 때 자주 유용합니다.

다음과 같은 SPA를 위해 작성한이 코드를 고려하십시오.

const actions = _.chain(options)
                 .pairs() // 1
                 .filter(selectActions) // 2
                 .map(createActionPromise) // 3
                 .reduce((state, pair) => (state[pair[0]] = pair[1], state), {}) // 4
                 .value();

이것은 상당히 복잡하지만 실제 시나리오였습니다. 무슨 일이 일어나고 있는지 설명하고 그 과정에서 Comma Operator에 대한 사례를 만드는 동안 저를 참아주십시오.


이것은 Underscore 의 연결을 사용 하여

  1. 사용하여이 함수에 전달 된 모든 옵션을 분해 pairs설정되는 { a: 1, b: 2}으로[['a', 1], ['b', 2]]

  2. 이 속성 쌍 배열은 시스템에서 '작업'으로 간주되는 항목으로 필터링됩니다.

  3. 그런 다음 배열의 두 번째 인덱스는 해당 작업을 나타내는 약속을 반환하는 함수로 대체됩니다 (사용 map).

  4. 마지막으로에 대한 호출 reduce은 각 "속성 배열"( ['a', 1])을 다시 최종 객체로 병합 합니다.

최종 결과는 options적절한 키만 포함하고 호출 함수에서 값을 사용할 수 있는 인수 의 변환 된 버전입니다 .


그냥보고

.reduce((state, pair) => (state[pair[0]] = pair[1], state), {})

reduce 함수가 빈 상태 객체로 시작하는 것을 볼 수 있으며 state키와 값을 나타내는 각 쌍에 대해이 함수는 state키 / 값 쌍에 해당하는 객체에 속성을 추가 한 후 동일한 객체를 반환합니다 . ECMAScript 2015의 화살표 함수 구문으로 인해 함수 본문은 표현식이며 결과적으로 쉼표 연산자는 간결하고 유용한 "반복" 함수를 허용합니다.

개인적으로 저는 ECMAScript 2015 + Arrow Functions를 사용하여보다 기능적인 스타일로 Javascript를 작성하는 동안 수많은 사례를 접했습니다. 그러나 화살표 기능을 만나기 전에 (예 : 질문 작성 당시) 쉼표 연산자를 고의적으로 사용하지 않았습니다.


쉼표 연산자의 또 다른 용도는 순전히 편의상 repl 또는 console에서 신경 쓰지 않는 결과를 숨기는 것입니다.

예를 들어, myVariable = aWholeLotOfTextrepl 또는 console에서 평가 하면 방금 할당 한 모든 데이터가 인쇄됩니다. 이것은 페이지와 페이지 일 수 있으며,보고 싶지 않은 경우 대신 평가할 수 myVariable = aWholeLotOfText, 'done'있으며 repl / console은 'done'만 인쇄합니다.

Oriel은 사용자 정의 toString()또는 get()기능이이를 유용하게 만들 수 있다고 올바르게 지적 합니다.


쉼표 연산자는 JavaScript에만 국한되지 않으며 C 및 C ++와 같은 다른 언어로도 사용할 수 있습니다 . 이항 연산자로서 이것은 일반적으로 표현식 인 첫 번째 피연산자가 두 번째 피연산자에 필요한 부작용을 가질 때 유용합니다. 위키 백과의 한 예 :

i = a += 2, a + b;

분명히 두 줄의 코드를 작성할 수 있지만 쉼표를 사용하는 것은 또 다른 옵션이며 때로는 더 읽기 쉽습니다.


나는 Flanagan에 동의하지 않으며, 쉼표는 정말 유용하며 특히 여러분이 무엇을하고 있는지 알고있을 때 더 읽기 쉽고 우아한 코드를 작성할 수 있다고 말합니다.

다음 은 쉼표 사용에 대한 매우 자세한 기사 입니다.

데모 증명을위한 몇 가지 예 :

function renderCurve() {
  for(var a = 1, b = 10; a*b; a++, b--) {
    console.log(new Array(a*b).join('*'));
  }
}

피보나치 생성기 :

for (
    var i=2, r=[0,1];
    i<15;
    r.push(r[i-1] + r[i-2]), i++
); 
// 0,1,1,2,3,5,8,13,21,34,55,89,144,233,377

jQuery .parent()함수 와 유사한 첫 번째 부모 요소를 찾습니다 .

function firstAncestor(el, tagName) {
    while(el = el.parentNode, el && (el.tagName != tagName.toUpperCase()));
    return el;
}

//element in http://ecma262-5.com/ELS5_HTML.htm
var a = $('Section_15.1.1.2'); 

firstAncestor(a, 'div'); //<div class="page">

I haven't found practical use of it other than that but here is one scenario in which James Padolsey nicely uses this technique for IE detection in a while loop:

var ie = (function(){

    var undef,
        v = 3,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');

    while ( // <-- notice no while body here
        div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
        all[0]
    );

    return v > 4 ? v : undef;

}());

These two lines must to execute :

div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]

And inside comma operator, both are evaluated though one could have made them separate statements somehow.


There is something "odd" that can be done in JavaScript calling a function indirectly by using the comma operator.

There is a long description here: Indirect function call in JavaScript

By using this syntax:

(function() {
    "use strict";
  
    var global = (function () { return this || (1,eval)("this"); })();
    console.log('Global === window should be true: ', global === window);
  
    var not_global = (function () { return this })();
    console.log('not_global === window should be false: ', not_global === window);
  
  }());

You can get access to the global variable because eval works differently when called directly vs called indirectly.


I've found the comma operator most useful when writing helpers like this.

const stopPropagation = event => (event.stopPropagation(), event);
const preventDefault = event => (event.preventDefault(), event);
const both = compose(stopPropagation, preventDefault);

You could replace the comma with either an || or &&, but then you'd need to know what the function returns.

More important than that, the comma separator communicates intent -- the code doesn't care what the left-operand evaluates to, whereas the alternatives may have another reason for being there. This in turn makes it easier to understand and refactor. If the function return type ever changes, the code above would not be affected.

Naturally you can achieve the same thing in other ways, but not as succinctly. If || and && found a place in common usage, so too can the comma operator.


One typical case I end up using it is during optional argument parsing. I think it makes it both more readable and more concise so that the argument parsing doesn't dominate the function body.

/**
 * @param {string} [str]
 * @param {object} [obj]
 * @param {Date} [date]
 */
function f(str, obj, date) {
  // handle optional arguments
  if (typeof str !== "string") date = obj, obj = str, str = "default";
  if (obj instanceof Date) date = obj, obj = {};
  if (!(date instanceof Date)) date = new Date();

  // ...
}

Let's say you have an array:

arr = [];

When you push onto that array, you are rarely interested in push's return value, namely the new length of the array, but rather the array itself:

arr.push('foo')  // ['foo'] seems more interesting than 1

Using the comma operator, we can push onto the array, specify the array as the last operand to comma, and then use the result -- the array itself -- for a subsequent array method call, a sort of chaining:

(arr.push('bar'), arr.push('baz'), arr).sort(); // [ 'bar', 'baz', 'foo' ]

Another area where comma operator can be used is Code Obfuscation.

Let's say a developper writes some code like this:

var foo = 'bar';

Now, she decides to obfuscate the code. The tool used may changed the code like this:

var Z0b=(45,87)>(195,3)?'bar':(54,65)>(1,0)?'':'baz';// Z0b == 'bar'

Demo: http://jsfiddle.net/uvDuE/

참고URL : https://stackoverflow.com/questions/9579546/when-is-the-comma-operator-useful

반응형