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

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

问题描述

假设我有以下对象构造函数:

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 演示

//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 :)

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

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