QR코드 에러

sangeun·2020년 3월 7일
0

QR코드를 일반 script 에서 type="module"로 바꾸니 문제가 생겼다.

갑자기 undefined에서 값을 불러오려고 한다는 것이다.

에러난 부분의 코드는 아래와 같다.

if (this._android && this._android <= 2.1) {
            var factor = 1 / window.devicePixelRatio;
            var drawImage = CanvasRenderingContext2D.prototype.drawImage;
            CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
                if (("nodeName" in image) && /img/i.test(image.nodeName)) {
                    for (var i = arguments.length - 1; i >= 1; i--) {
                        arguments[i] = arguments[i] * factor;
                    }
                } else if (typeof dw == "undefined") {
                    arguments[1] *= factor;
                    arguments[2] *= factor;
                    arguments[3] *= factor;
                    arguments[4] *= factor;
                }

                drawImage.apply(this, arguments);
            };
        }

왜 갑자기 이전에는 window에 잘 바인딩되던 this가 이번에는 undefined로 바인딩 되어 에러가 발생한 것이다.

자세히 알아보니 모듈 방식은 strict모드를 사용한다는 것을 알게 되었고
strict모드에서는 전역에서 this가 window로 바인딩되지 않는다는 것을 깨달았다.

즉, 순서대로 생각하면 이 new QRCode()를 실행하는 곳은 모듈이었기 때문에 this는 undefined로 바인딩된다. 여기서 생성자를 호출해 QRCode 인스턴스를 생성했다면, 그 인스턴스는 호출한 곳의 this에 바인딩되고, 그 인스턴스의 this도 undefined가 된다.

const printCode = (url) => {
  const qrCode = new QRCode("qrcode", qrOption);

  qrCode.makeCode(url);
};

그러면 해결책은
1. 인스턴스의 this를 window로 바인딩
2. strict모드를 취소
3. 코드를 수정

이렇게 세가지 방법이 있을 수 있다.
하지만 1번의 경우, new를 통해 객체의 인스턴스를 생성하는 작업에 call함수를 통해 this를 바인딩하는 것은 불가능했다.
또한 2번도 찾아본 결과 불가능했다.
결국 this에러가 발생하는 코드를 window로 직접 수정해보기로 하였고, 일단 한 줄만 수정해서 해결이 되었다.

하지만 현재 상황에서만 잘 동작하지, 다른 상황에서는 어떻게 동작할지 모르므로 코드를 직접 읽고 이해해서 고치거나, 모듈 방식이 아니라 script방식을 그대로 사용하는 것이 좋을 것 같다.

profile
꾸준히

0개의 댓글