[javascript] 자바 스크립트에서 소문자 “f”를 사용하는`new function ()`

제 동료는 소문자 “f”와 함께 “new function ()”을 사용하여 JavaScript에서 새 개체를 정의했습니다. 모든 주요 브라우저에서 잘 작동하는 것처럼 보이며 개인 변수를 숨기는데도 상당히 효과적입니다. 예를 들면 다음과 같습니다.

    var someObj = new function () {
        var inner = 'some value';
        this.foo = 'blah';

        this.get_inner = function () {
            return inner;
        };

        this.set_inner = function (s) {
            inner = s;
        };
    };

“this”가 사용되는 즉시 someObj의 공용 자산이됩니다. 따라서 someObj.foo, someObj.get_inner () 및 someObj.set_inner ()는 모두 공개적으로 사용할 수 있습니다. 또한 set_inner () 및 get_inner ()는 권한이있는 메소드이므로 클로저를 통해 “내부”에 액세스 할 수 있습니다.

그러나 나는이 기술에 대한 언급을 어디서도 보지 못했습니다. Douglas Crockford의 JSLint조차도 이에 대해 불평합니다.

  • 이상한 건설. ‘신규’삭제

우리는이 기술을 프로덕션에 사용하고 있고 잘 작동하는 것 같지만 어디에도 문서화되어 있지 않기 때문에 약간 불안합니다. 이것이 유효한 기술인지 아는 사람이 있습니까?



답변

나는 이전에 그 기술을 보았고, 유효하며, 마치 Constructor Function 인 것처럼 함수 표현식을 사용하고 있습니다 .

그러나 IMHO, 자동 호출 함수 표현식으로 동일한 결과를 얻을 수 있습니다 new. 그런 식으로 연산자 를 사용하는 요지는 실제로 보이지 않습니다 .

var someObj = (function () {
    var instance = {},
        inner = 'some value';

    instance.foo = 'blah';

    instance.get_inner = function () {
        return inner;
    };

    instance.set_inner = function (s) {
        inner = s;
    };

    return instance;
})();

new연산자 의 목적은 새 개체 인스턴스를 만들고 [[Prototype]]내부 속성을 설정하는 것입니다. 내부 속성에 의해 어떻게 만들어 지는지 확인할 수 있습니다 [Construct].

위의 코드는 동등한 결과를 생성합니다.


답변

귀하의 코드는 덜 이상한 구조와 비슷합니다.

function Foo () {
    var inner = 'some value';
    this.foo = 'blah';

    ...
};
var someObj = new Foo;


답변

몇 가지 측면을 명확히하고 Douglas Crockford의 JSLint가 귀하의 코드에 대해 불평하지 않도록하기 위해 여기에 인스턴스화의 몇 가지 예가 있습니다.

1. o = new Object(); // normal call of a constructor

2. o = new Object;   // accepted call of a constructor

3. var someObj = new (function () {
    var inner = 'some value';
    this.foo = 'blah';

    this.get_inner = function () {
        return inner;
    };

    this.set_inner = function (s) {
        inner = s;
    };
})(); // normal call of a constructor

4. var someObj = new (function () {
    var inner = 'some value';
    this.foo = 'blah';

    this.get_inner = function () {
        return inner;
    };

    this.set_inner = function (s) {
        inner = s;
    };
}); // accepted call of a constructor

예제 3. (…)의 표현식 값은 함수 / 생성자입니다. 다음과 같이 보입니다 : new (function () {…}) (). 따라서 예제 2에서와 같이 끝 괄호를 생략해도 표현식은 여전히 ​​유효한 생성자 호출이며 예제 4처럼 보입니다.

Douglas Crockford의 JSLint는 인스턴스가 아닌 someObj에 함수를 할당하기를 원했습니다. 결국 그것은 오류가 아니라 경고 일뿐입니다.


답변