返回其自身实例的Object

Lev*_*son 11 javascript library-design

背景:我的最新项目不能使用大型图书馆,这让我感到很难过.有几件事情,我想从任何图书馆有,如缺少的功能addClass,hasClass,removeClass,兼容addEventListener,等等.所以我创建了一个小东西,我想一些其他的时间了一些意见,但我有一个设置它的方式有点麻烦.

为了方便使用,我希望一个对象在创建时返回自己的新实例.

鉴于:

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

    return this;
};

console.log($());
Run Code Online (Sandbox Code Playgroud)

我们得到DOMWindow而不是$因为thisJavaScript 中的古怪性质. 对我来说更奇怪的是,console.log(new $().name)正确地返回"levi".如果this绑定到窗口,为什么对象正确获取值?.我们可以添加新的console.log(new $()),它的工作原理.但是,我不想每次都写新的.所以我尝试过:

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

    return new obj();
};

console.log($());
Run Code Online (Sandbox Code Playgroud)

这给了我想要的东西,但是将对象包装在创建它的函数中似乎没有必要.更进一步,返回的对象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
Run Code Online (Sandbox Code Playgroud)

它似乎在我的所有测试中都有效.

Koo*_*Inc 6

我想要的最简单的方法是(我认为):

$ = function(){
    if (!(this instanceof $)){
     return new $;
    }
    this.name = 'levi'; 
    return this;
}
Run Code Online (Sandbox Code Playgroud)

仅仅返回this并不创建$实例的事实是因为this创建方式是$作为常规函数执行的:在这种情况下,this指向全局对象的值(在浏览器中:window,实际上调用执行$()window.$())。可以这么说,这是JavaScript生活的事实。console.log(new $().name)显示正确值的事实是因为您将函数作为构造函数调用,该函数返回该构造函数的实例(即的新实例$)。但是console.log($().name)也会打印'levi',因为它返回具有属性的全局对象name,即window.name。试试看$(); console.log(name),您会发现name现在是一个全局变量。因此,如果您不想使用new每次使用关键字作为关键字,请检查您的函数是作为常规函数调用,还是作为=== instanceof $构造函数内实例()的构造函数调用。使用上述方法,实例构造函数无论使用或不使用实例化,new都将始终$

也许您应该将问题的标题改写为:“一个返回其自身实例的 Object [constructor] ”

也许此博客条目可以揭示更多信息。


ick*_*fay 5

jQuery不会它的方式是,如果第一次测试thiswindow(作为函数调用),如果是的话,返回自己的新实例.例如:

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

console.log($());
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为当你正常调用函数(func())时,this它将与调用者的函数相同this.(相关但不无关系:obj.method()必须thisobj)因为默认范围是window,this里面$window当你调用它$().

当你使用函数调用时new,会发生什么是JavaScript创建一个新对象,然后使用thisset设置为该对象来调用你的函数.

该解决方案的工作,因为它第一次测试,如果thiswindow,因此,被称为像$().如果它被称为$(),它将返回new $().否则,它被调用new $(),并将按预期工作.