我正在研究underscore.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.
我试图找出_
(下划线)在这里做了什么:我认为它作为构造函数并返回一个实例,其中包含在underscore.js中定义的所有函数。因此,用简单的语法调用函数会更方便。
Fox示例:
var anotherList = [1, 2];
_.each(anotherList, alert); // alert "1", "2"
var anotherObj = {"name": "H"};
var anotherObj = _(anotherObj);
anotherObj.each(alert); // alert "H"
但这背后的机制是什么?
this._wrapped = obj;
如何运作?
答案 0 :(得分:5)
顶部的功能"有点像"某种东西的构造函数,有点像" JavaScript中的一个类(非常宽松的描述:搜索prototype
,class
和javascript
以获得更高的准确性。)
在这种情况下,"类"有一个成员(._wrapped
),它被设置为指定的对象(obj
)。 (在其他地方,在underscore.js
中,"类"的所有功能都将使用.prototype
添加。)
一开始的两个测试是为了防止错误使用:
if (obj instanceof _) return obj;
检查您是否没有将_
类的实例传递给构造函数(如果这样做,它只返回该实例)。这将停止:
var a = {...};
var b = new _(a);
var c = new _(b);
创建一个双重包装的对象(c
将与b
相同。)
第二次测试:
if (!(this instanceof _)) return new _(obj);
在创建实例时检查您是否正确使用了new
(或者相反,允许您不必记住始终使用new
。
在代码中调用时:
var test = _(obj);
this
函数内_
的值将是全局范围,因此不是_
类的实例。在这种情况下,它将使用new
来创建_
类的新实例并将其返回。 (如果它没有这样做,并且你没有使用new
,那么你就不会得到一个新对象,最终会污染全局对象。)
如果在上面的示例中调用它(使用new
),则函数内的this
将是新创建的_
对象。这个将成为instanceof _
,因此将继续进行构造函数的主要部分:
this._wrapped = obj;
保存包装在新实例中的对象的副本。因此:
var a = {...};
var b = _(a);
var c = new _(a);
将同时创建b
和c
作为_
类的新实例。无论你应该使用new
,还是依赖构造函数为你做这件事都是另一个问题。
答案 1 :(得分:4)
_
函数是递归的。你打电话给它,然后它第二次称自己。我们来看看。
var _ = function(obj) {
if (obj instanceof _) return obj;
if (!(this instanceof _)) return new _(obj);
this._wrapped = obj;
};
当您使用_(obj)
执行obj={...}
时,您的对象符合第二个if
条件 - this
不是_
的实例,因为它是没有被称为构造函数(this
是全局对象)。然后,它返回new _(obj)
,调用_
作为构造函数。第二次,this
确实是_
的一个实例,所以这两个条件都没有实现。现在,它到达最后一行。作为构造函数,它会在您第一次调用它时隐式返回this
。
您现在有一个_
对象。