Giter VIP home page Giter VIP logo

Comments (1)

indongyoo avatar indongyoo commented on July 21, 2024 2

반갑습니다. 지환님! 넘나 고급지고 실제적인 질문 감사합니다. 이렇게 실제 코드에 대한 질문은 언제나 환영이고, 정말 좋습니다.


아래 each는 Iterable과 object를 순회하는 each의 간단 버전입니다 valuesIter는 기본 object를 기준으로 구현한 함수이기 때문에 모든 key에 해당하는 값을 순회합니다. 애초에 기본 객체가 아니면 순회를 할 이유가 거의 없기도 하고, 기본 객체의 사용을 권장하기 때문에 Functional.es의 ObjIter.values에서도 동일하게 적용했습니다.

function *valuesIter(obj) {
  for (const key in obj) yield obj[key];
}

function each(f, coll) {
  const iter = typeof coll[Symbol.iterator] == 'function' ?
    coll : valuesIter(coll);

  for (const val of iter) f(val);

  return coll;
}

const users = {
  5: { id: 5, name: 'YB' },
  19: { id: 19, name: 'BX' },
  27: { id: 27, name: 'MD' }
};

each(u => console.log(u.name), users);
// YB
// BX
// MD

그러므로 질문주신대로 만일 기본 객체가 아닌 객체를 순회하려고 하면 다음과 같은 문제가 생깁니다.

function CustomObject(object) {
  Object.assign(this, object);
}
CustomObject.prototype.get = function(key) {
  return this[key];
};
CustomObject.prototype.set = function(key, val) {
  this[key] = val;
  return this;
};

const customObject = new CustomObject({
  a: 'A',
  b: 'B'
});

console.log(customObject);
each(a => console.log(a), customObject);
// A
// B
// f (key) {
//     return this[key];
//   }
// f (key, val) {
//     this[key] = val;
//     return this;
//   }

위 문제를 해결하기 위해 each안에서 사용하고 있는 valuesIterif를 추가하는 것도 방법이지만, 만능이 되기 위해 안쪽 깊숙한 곳에 if를 넣을 필요는 없습니다. 분기는 사실 each에 넣기전에 함수 조합을 통해서도 만들 수 있습니다.

function *valuesIter2(obj) {
  for (const key in obj)
    if (obj.hasOwnProperty(key)) yield obj[key];
}
each(console.log, valuesIter2(customObject));
// A
// B

each의 인자인 coll은 Iterable/Iterator 프로토콜을 지원하기 때문에, 이것을 기반으로 valuesIter2와 같은 함수를 통해 프로토콜을 맞춰줄 수 있습니다. 이처럼 안쪽 깊숙한 곳에서 분기를 하기보다 최대한 바깥쪽에서 분기를 하면 오류율을 줄일 수 있습니다. 대부분의 분기는 바깥에서 정할 수 있습니다. 만능 함수 한 개보다 작은 함수 10개가 낫습니다. 위와 같이하면 each의 성능을 하향 평준화시킬 필요가 없게 되기도 합니다.

이건 별개의 이야기인데요. class 키워드를 사용하면 hasOwnProperty가 필요 없기도 합니다.

class CustomObject2 {
  constructor(object) {
    Object.assign(this, object);
  }
  get(key) {
    return this[key];
  }
  set(key, val) {
    this[key] = val;
    return this;
  }
}
each(console.log, new CustomObject2({a:1, b: 2}));
// 1
// 2

결론을 내리자면, 이와 같은 전략을 취할 수 있는 것은 ES6을 기반으로 할 때에 이야기일 것 같습니다. 자바스크립트의 발전과정에서 말씀하셨던 문제가 생겼고, hasOwnProperty가 그것의 해결을 위해 있는 헬퍼 함수이기도 합니다. 그래서 말씀주신대로 hasOwnProperty나 Object.keys의 활용이 거의 필수였고요. 자바스크립트가 더 발전하여 class 키워드를 사용할 수 있게 되었고(아직 모든 곳에서는 아니지만), for...of와 for...in은 더욱 자주, 잘 쓰일 기능이 될 것 입니다 :)

from functionales.

Related Issues (3)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.