Javascript Underline.js中的函数(对象包装器)是如何工作的?

Javascript Underline.js中的函数(对象包装器)是如何工作的?,javascript,underscore.js,Javascript,Underscore.js,我正在使用underline.js,我被困在了第一个函数中 // Create a safe reference to the Underscore object for use below. var _ = function(obj) { if (obj instanceof _) return obj; if (!(this instanceof _)) return new _(obj); this._wrapped = obj; }; // Test Exa

我正在使用underline.js,我被困在了第一个函数中

// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
    if (obj instanceof _) return obj;
    if (!(this instanceof _)) return new _(obj);
    this._wrapped = obj;
  };

// Test Examples
var obj = {
    name : 'Francis',
    gender: 'male'
}
var test = _(obj);
console.log(test); // _ {_wrapped: Object}
                   // Why statement this._wrapped = obj; still got executed?

var Man = function() {
    this.age = 30;
    this.people = "John";
    return this;
    this.man = "me";
}
var me = new Man();
console.log(me) // Man {age: 30, people: "John"}
                // There is no "man" property because function Man returns
                // before executing to the last statement.
我试图弄清楚
\uuu
(下划线)在这里做什么:我认为它充当构造函数并返回一个实例,其中包含在underline.js中定义的所有函数。因此,使用简单的语法调用函数会更方便

例如:

var anotherList = [1, 2];
_.each(anotherList, alert); // alert "1", "2"

var anotherObj = {"name": "H"};
var anotherObj = _(anotherObj);
anotherObj.each(alert); // alert "H"
但这一切背后的机制是什么


如何
this.\u wrapped=obj工作?

顶部的函数“有点像”JavaScript中类的构造函数(非常松散的描述:搜索
prototype
class
JavaScript
,以获得更高的准确性)

在这种情况下,“类”有一个成员(
\u wrapped
),该成员被设置为指定的对象(
obj
)。(在其他地方,在
underline.js
中,将使用
.prototype
添加“类”的所有函数)

开始时的两项测试旨在防止错误使用:

if (obj instanceof _) return obj;
检查您是否没有将
\uuu
类的实例传递到构造函数中(如果传递,它只返回该实例)。这将停止:

var a = {...};
var b = new _(a);
var c = new _(b);
创建双重包装对象(
c
将与
b
相同)

第二个测试:

if (!(this instanceof _)) return new _(obj);
检查您在创建实例时是否正确使用了
new
(或者相反,允许您不必一直记住使用
new

在代码中调用时:

var test = _(obj);
函数中的
this
的值是
\u
的全局范围,因此不是
\u
类的实例。在本例中,它将使用
new
为您创建
\uu
类的新实例并返回它。(如果它不这样做,并且您没有使用
new
,那么您就不会得到一个新对象,最终会污染全局对象)

如果在上面的示例中调用它(使用
new
),那么函数中的
这个
将是新创建的
\uu
对象。这将是一个
实例,因此将进入构造函数的主要部分:

this._wrapped = obj;
这将保存正在新实例中包装的对象的副本。因此:

var a = {...};
var b = _(a);
var c = new _(a);

将创建
b
c
作为
类的新实例。您是应该使用
新的
,还是依赖构造函数来为您执行此操作,这是另一个时间的问题。

函数是递归的。你叫它,然后它再叫它自己。让我们看一下。

var _ = function(obj) {
    if (obj instanceof _) return obj;
    if (!(this instanceof _)) return new _(obj);
    this._wrapped = obj;
  };
当您使用
obj={…}
执行
(obj)
操作时,您的对象满足第二个
条件--
不是
的实例,因为它不是作为构造函数调用的(
是全局对象)。然后,它返回
new(obj)
,并作为构造函数调用
。第二次,
这个
确实是
的一个实例,所以两个条件都没有满足。现在,它到达了最后一行。作为构造函数,它隐式地将
返回到您第一次调用它时


您现在有了一个
\u
对象。

问题的主体与标题完全不同。你想回答哪个问题?哦,
\u
只是一个标识符的有效名称。实际上它有点像这个问题:。但是在阅读了很多相关的问题后,我仍然不明白它是如何工作的。它解释了很多!但是
如何测试每个(警报)
工作?在underline.js源代码中,
.\uj.each(obj,iteratee,[context])
至少接受两个参数,而这里我们只传递一个
iteratee
参数给它,它仍然可以工作。因为您有一个包装的下划线对象,它可以设置所有这些属性。