//function returning an object is a possibility. bar has access to elem because of
// the shared scope
function foo ( elem ) {
return {
bar : function () {
return elem.id;
}
};
}
在这个中,foo 函数返回一个对象,其中包含您想要的任何方法。因此,当您拨打foo 时,您会收到以下信息:
{
bar : function () {
return elem.id;
}
}
elem 在您致电foo 时出现。如果您要在bar 的顶部添加console.log( elem ),您会发现它与您传递给foo 的内容相同。
//this is kinda how jQuery does it:
var foo = (function() {
function foo ( elem ) {
this.elem = elem;
}
foo.prototype.bar = function () {
return this.elem.id;
};
return function ( elem ) {
return new foo( elem );
};
}());
这个稍微复杂一点,实际上一分为二。
function foo ( elem ) {
this.elem = elem;
}
foo.prototype.bar = function () {
return this.elem.id;
};
谁不喜欢与经典继承名称混合的原型继承?无论如何...函数既可以作为常规函数,也可以作为构造函数。这意味着,当使用 new 关键字调用时,会发生两件特殊的事情:
-
this 内部的foo 指的是新制作的foo.prototype 的副本
-
foo.prototype 被返回(除非foo 返回一个对象)
请注意,foo.prototype 不是一个神奇的值。它就像任何其他对象属性一样。
所以,在foo 函数/构造函数中,我们只是设置foo.prototype.elem,而不是直接设置。可以这样想(有点不准确,但可以):foo.prototype 是产品的蓝图。每当您想制作更多时,就使用蓝图-复制里面的东西,然后传递。在foo 内部,this 指的是蓝图的这种复制。
但是,通过显式设置 foo.prototype 的值,我们正在更改蓝图本身。每当调用 foo 时,都会使用这个更改后的蓝图调用它。
最后,一旦foo 完成,复制(复制的蓝图,但在foo 完成后)被返回。此复制包含原始蓝图以及我们可能添加的所有其他内容 - 在此示例中为 elem。
var foo = (function() {
...
return function ( elem ) {
return new foo( elem );
};
}());
我们创建一个无名函数并立即执行它。
(function () {
console.log( 'meep' );
}());
//is the equivalent of:
var something = function () {
console.log( 'meep' );
};
something();
something = undefined; //we can no longer use it
//and of this
function () {
console.log( 'meep' );
}(); //<--notice the parens
//however, it's considered good practice to wrap these self-executing-anonymous-functions
// in parens
像所有其他函数一样,它们可以返回值。并且这些值可以被捕获到变量中。
var answer = (function () {
return 42;
}());
answer ==== 42;
var counter = (function () {
var c = 0;
return function () {
return c++;
};
}());
//counter is now a function, as a function was returned
counter(); //0
counter(); //1
counter(); //2...
所以:
var foo = (function () {
...
return function ( elem ) {
...
};
}());
返回一个接收参数的函数,该函数现在分配给foo。
函数内部:
return new foo( elem );
是为了确保我在上面谈到的特殊条件 - 它通过明确执行new 操作来确保制造蓝图的新副本。这实际上可以像这样复制:
function foo ( elem ) {
this.elem = elem;
}
foo.prototype.bar = function () {...};
只要您总是使用 new 关键字调用 foo。