即使忘记了“新”,我应该何时自动创建一个对象? [英] When should I automatically create an object even if `new` is forgotten?

查看:130
本文介绍了即使忘记了“新”,我应该何时自动创建一个对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有以下对象构造函数:

Let us say I have the following object constructor:

function Foo(bar) {
    this.bar = bar;
}

如果我在没有 new 关键字然后 bar 将在任何范围内设置 Foo()被调用:

If I run the function in the global scope without the new keyword then bar will be set in whatever scope Foo() is called in:

var foo = Foo(42);
console.log(bar); // 42
console.log(foo.bar); // ERROR

所以我的想法是做这样的事情:

So my idea is to do something like this:

function Foo(bar) {
    if(!(this instanceof Foo)) {
        // return a Foo object
        return new Foo(bar);
    }
    this.bar = bar;
}

如果我这样做 new Foo(42) Foo(42) 始终 返回一个 Foo 对象。

That way if I do new Foo(42) or Foo(42), it would always return a Foo object.

这个曾经是个好主意吗?如果是的话,何时?何时(和为什么)避免这种技术是明智的?

Is this ever a good idea? If so, when? When (and why) would it be wise to avoid this technique?

推荐答案

这对于内部构造对象包装器时非常有用。

This can be useful for when you would like to internally construct an object wrapper.

一个鲜为人知的库在内部使用这种方法,jQuery。

A little known library internally uses this approach, jQuery.

他们不使用 instanceof 不再接近。每次调用jQuery时,它都会自动执行此操作:

They do not use the instanceof approach any longer though. Every time jQuery is called, it automatically does this:

// Define a local copy of jQuery
jQuery = function( selector, context ) {
 // Need init if jQuery is called (just allow error to be thrown if not included)
 return new jQuery.fn.init( selector, context );
}

它所做的一切都在内部引用本地副本。在其工作的最后,它将它附加到全局范围

Everything it does internally references this local copy. At the very end of its work, it then attaches it to the global scope

window.jQuery = window.$ = jQuery;

所以每次拨打 $()它在内部使用 new 。它还假设您在外部使用 new ,但它确实无关紧要。

So every time you call $() it internally uses new. It is also assuming that you do not use new externally, but it really doesn't care if you do or not.

编辑

jsFiddle演示

jsFiddle Demo

//Foo entrance
function Foo(bar){
 //construct a new Foo object to return
 return new Foo.prototype.build(bar);
}

//constructor for returning new prototype
Foo.prototype.build = function(bar){
 //initialize base settings
 this.bar = bar;
 //chain object
 return this;
};

//this is the complex part
//tie the prototype of Foo.prototype.build.prototype to Foo.prototype
//so that is "seems" like Foo is the parent of the prototype assignments
//while allowing for the use of returning a new object in the Foo entrance
Foo.prototype.build.prototype = Foo.prototype;

//simple expansions at this point, nothing looks too different
//makes a function for a constructed Foo that logs hello
Foo.prototype.hello = function(){
 console.log("Hello "+this.bar+" :)");
 //returns this for chaining
 return this;
};

//more extensions, this one changes this.bar's value
Foo.prototype.setBar = function(arg){
 //accesses the current Foo instance's .bar property
 this.bar = arg;
 //returns this for chianing
 return this;
};

//should be seeing a pattern
Foo.prototype.goodbye = function(){
 console.log("Bye "+this.bar+" :(");
 return this;
};

var foo = Foo(42);
//console.log(bar); // ERROR
console.log(foo.bar); // 42
foo.hello(); //Hello 42 :)
foo.hello().setBar(9001).goodbye(); //Hello 42 :) Bye 9001 :(
Foo(12).hello(); //Hello 12 :)

这篇关于即使忘记了“新”,我应该何时自动创建一个对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆