문제

배경: 내 최근 프로젝트에서는 대규모 라이브러리를 사용할 수 없어서 안타깝습니다.누락된 함수와 같이 모든 라이브러리에서 갖고 싶은 몇 가지 사항이 있습니다. addClass, hasClass, removeClass, 호환 가능 addEventListener, 등.그래서 내가 만들었어요 작은 물건 나중에 의견을 듣고 싶지만 원하는 대로 설정하는 데 약간의 어려움이 있습니다.

이용편의를 위해, 나는 객체가 생성될 때 자신의 새로운 인스턴스를 반환하기를 원합니다.

주어진:

 $ = function() {
    this.name = "levi";

    return this;
};

console.log($());

대신 DOMWindow를 얻습니다. $ 그 특이한 성격 때문에 this 자바스크립트에서. 나에게 더 이상한 점은 console.log(new $().name) "levi"를 올바르게 반환합니다.만약에 this 창에 바인딩되어 있는데 왜 개체가 값을 올바르게 얻었습니까?.그냥 새로 추가하면 돼요 console.log(new $()) 그리고 그것은 작동합니다.하지만 매번 새로운 글을 쓰고 싶지는 않습니다.그래서 나는 다음을 시도했습니다.

$ = function() {
    var obj = function() {
        this.name = "levi";
    };

    return new obj();
};

console.log($());

내가 원하는 것을 제공하지만 객체를 생성하는 함수 내부에 객체를 래핑하는 것은 약간 불필요한 것 같습니다.게다가 반환된 객체는 다음과 같습니다. obj 그리고는 아니다 $.비교 테스트가 실패합니다.

이를 수행할 수 있는 다른 방법은 무엇입니까? 더 우아한 솔루션이 있습니까?나는 내 전체 과정을 다시 생각하는 것에 대해 아무런 불만이 없습니다.나는 JavaScript를 꽤 잘 사용한다고 생각하지만, 새로운 JavaScript를 만드는 것은 나에게 매우 새로운 일입니다.


다음 해결 방법에 문제가 있는 사람이 있습니까?

$a = function() {};

$ = function() {
    if (!(this instanceof $)) {
        return new $();
    }

    this.name = "levi";

    return this;
};

//helper function
var log = function(message) {
    document.write((message ? message : '') + "<br/>");
};

log("$().name == window.name: " + ($().name == window.name)); //false
log("$().name: " + $().name); //levi
log("window.name: " + window.name); //result

log();

log("$a instanceof $: " + ($a instanceof $)); //false
log("typeof $a: " + (typeof $a)); //function
log("typeof $: " + (typeof $)); //function

모든 테스트에서 작동하는 것 같습니다.

도움이 되었습니까?

해결책

원하는 것을 수행하는 가장 간단한 방법은 다음과 같습니다.

$ = function(){
    if (!(this instanceof $)){
     return new $;
    }
    this.name = 'levi'; 
    return this;
}

이제 막 돌아왔다는 사실 this $의 인스턴스를 생성하지 않는 이유는 다음과 같습니다. this 생성되어 실행됩니다. $ 일반 기능으로:이 경우의 값은 this 전역 객체를 가리킵니다(브라우저 내에서: window, 실제로 실행을 호출합니다. $() 와 같다 window.$()).말하자면 그것은 자바스크립트 생활의 사실입니다.사실 그 console.log(new $().name) 올바른 값을 보여주는 것은 해당 생성자의 인스턴스를 반환하는 생성자로 함수를 호출하기 때문입니다(예:새로운 인스턴스 $).하지만 console.log($().name) 속성이 있는 전역 객체를 반환하므로 'levi'도 인쇄합니다. name, 즉. window.name.노력하다 $(); console.log(name) 그리고 당신은 보게 될 것입니다 name 이제 전역 변수입니다.그러니 이 기능을 사용하고 싶지 않다면 new 매번 키워드를 사용하여 함수가 일반 함수로 호출되는지 아니면 인스턴스의 생성자로 호출되는지 확인하세요(=== instanceof $) 생성자 함수 내에서.위의 메서드를 사용하면 인스턴스 생성자가 있든 없든 관계없이 인스턴스 생성자가 됩니다. new 언제나 그럴 것이다 $

질문 제목을 다음과 같이 바꿔야 할 수도 있습니다.'를 반환하는 객체 [생성자] 그 자체의 인스턴스'

아마도 이 블로그 항목 여분의 빛을 발산할 수 있습니다.

다른 팁

jQuery가 수행하는 방식은 먼저 다음을 테스트합니다. this ~이다 window (함수라고 함), 그렇다면 자신의 새 인스턴스를 반환합니다.예를 들어:

var $ = function() {
    if(this === window) {
        return new $();
    }
    this.name = "levi";
    return this;
};

console.log($());

이는 일반적으로 함수를 호출할 때(func()), this 발신자와 동일합니다. this.(관련이 있지만 관련이 없는 것은 아닙니다: obj.method() 가질 것이다 this BE obj) 기본 범위는 다음과 같습니다. window, this 내부에 $ 될거야 window 당신이 그것을 다음과 같이 부를 때 $().

다음을 사용하여 함수를 호출할 때 new, JavaScript가 새 객체를 생성한 다음 다음을 사용하여 함수를 호출하면 어떻게 되나요? this 해당 개체로 설정합니다.

이 솔루션은 다음을 먼저 테스트하기 때문에 작동합니다. this ~이다 window, 따라서 다음과 같이 호출되었습니다. $().만약 그것이 다음과 같이 불렸다면 $(), 돌아올 것이다 new $().그렇지 않으면 다음과 같이 호출되었습니다. new $(), 예상대로 작동합니다.

>  $ = function() {
>     this.name = "levi";
> 
>     return this; };
> 
> console.log($());

$ 대신 DOMWindow를 얻습니다.

당신이 전화할 때 $ 기능적으로는 이것 키워드는 그런 식으로 호출되는 모든 함수와 마찬가지로 전역 객체로 설정됩니다.

JavaScript에서 이것의 기발한 특성 때문에

자바스크립트의 이것 키워드*는 작동하도록 지정된 대로 작동합니다.다른 언어와는 다르지만 그것이 작동하는 방식입니다.

나에게 더 이상한 것은 Console.log ($ (). name)이 "levi"를 올바르게 반환한다는 것입니다.

당신이 전화할 때 $ 함수로서, 이것 키워드는 전역 개체이므로 다음과 같습니다.

this.name = 'levi';

라는 전역 객체의 속성을 생성합니다. 이름 값은 'levi'입니다.무슨 일이 일어나고 있는지 알면 이상하지 않습니다.:-)

우리는 단지 새로운 콘솔을 추가 할 수 있습니다 (new $ ()).

이것이 자바스크립트에서 생성자를 호출하는 방식입니다.함수가 호출될 때 새로운, 그것은 이것 키워드는 새로 생성된 객체로 설정되므로 this.name 해당 개체의 새 속성을 만듭니다.그런데, return this 중복되고 생성자가 반환됩니다. 이것 기본적으로.

> $ = function() {
>     var obj = function() {
>         this.name = "levi";
>     };
> 
>     return new obj(); };

console.log($());그것은 내가 원하는 것을 제공하지만, 그것을 생성하는 함수 내부의 객체를 감싸는 것은 약간 불필요한 것 같습니다.더욱

아마도 당신은 유형, ECMA-262에서 지정한 값 중 하나만 반환할 수 있습니다.짧은 목록(객체, 숫자, 문자열 등 포함)에는 다음이 포함되지 않습니다. $.

이것이 할 수있는 다른 방법은 무엇입니까?

이미 발견한 접근 방식인 Lasse Reichstein Nielsen의 복제본(Doublas Crockford에서 "beget"로도 유명함)과 Richard Cornford의 모듈 패턴을 사용할 수 있습니다.Google을 사용하면 위의 모든 항목에 대한 게시물이 아주 많습니다.

다음과 같이 시도해 보십시오.

function $(name){
    if( !(this instanceof arguments.callee) ){
        return new arguments.callee(name);
    }
    this.name = name;
    return this;
}

업데이트:

@레비 모리슨

편집하다:다음 해결 방법에 문제가 있는 사람이 있습니까?

물어보셨기 때문에, 나는 document.write를 별로 좋아하지 않는다..
대신 이것을 시도해 보세요:

var log = function(message){
    if(message){
        document.body.appendChild(document.createTextNode(message));
    }
    document.body.appendChild(document.createElement('br'));
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top