为了方便使用,我想要一个对象在创建时返回一个新的实例.
鉴于:
$= function() { this.name = "levi"; return this; }; console.log($());
我们得到DOMWindow而不是$,因为它在JavaScript中的奇怪本质.更奇怪的是,console.log(new $().name)正确返回“levi”.如果这绑定到窗口,为什么对象正确地获取值?我们可以添加新的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; }
事实上,只是返回这个没有创建一个$的实例是因为这样创建执行$作为常规函数的方式:在这种情况下,这个值指向全局对象(在浏览器中:窗口中,实际调用执行$()与窗口相同$()).这是一个javascript生活的事实可以说. console.log(new $().name)显示正确的值是因为您将该函数作为构造函数调用,该构造函数返回该构造函数的实例(即新的$实例).但是console.log($().name)也会打印’levi’,因为它返回带有属性名称的全局对象,即window.name.尝试$(); console.log(name),你会看到name是一个全局变量.因此,如果您不想每次都使用new关键字,请检查您的函数是否被调用为常规函数,或者作为构造函数中的实例(=== instanceof $)的构造函数.使用上述方法,一个实例构造函数,无论是否使用新的实例,都将是$
也许你应该把你的问题的标题改成:’返回一个自己的实例的对象[构造函数]
也许this blog entry可以减轻额外的光线.