() 看《js设计模式》时,发现个问题…

我看这里的时候 感觉有个很奇怪的地方:

var getSingle = function fn { var result; return function{ return result || result = fn .applythis, arguments ; }
};

在调用 getSingle的时候,每次调用 都会重新声明一个 var result 变量啊, 所以每次 result 都是个新的 空 呀,那后面的判断 就没意义了!!!是不是漏了个立即执行function{} 来包裹一下呀?

嗯 这书我也看过 《JavaScript设计模式与开发实践》,单例模式那块儿。

其实这是一个闭包的问题

你看这一行

var createSingleLoginLayer = getSinglecreateLoginLayer

返回的这个 createSingleLoginLayer 函数始终引用了 result 变量。

因此假设 无论是 createSingleLoginLayerargs1 还是 createSingleLoginLayerargs2 其实result 变量从来都是那个一开始那个 result .每次 result 不是空的。

说到底,这就是个闭包的问题。

@499311496 说的是对的。
这个getSingle是把创建单例的方法也抽象出来,每次调用getSingle,result的确会被再创建一次。但是第二次创建的跟第一次是没有关系的。比如:

var createSingleLoginLayer = getSinglecreateLoginLayer

上面result被创建了一次,但是我是用于创建登录窗口的。我接着再使用:

var createSingleLogoutLayer = getSinglecreateLogoutLayer

result又被创建了一次,但是这个时候两个result也都是存在的,并且是不一样的。我现在即可以使用createSingleLoginLayer又可以使用reateSingleLogoutLayer。

题主说的没有问题,每次调用getSingle的时候都会重新声明一个result,但是书上没有写错,getSingle的作用并不是获得单例,而是获得生产单例的函数,createSingleIframe函数才是获得单例;每次运行createSingleIframe函数其中的result不会被重新声明,因为createSingleIframe函数每次执行的是返回的函数。

var createFrame = function{ var iframe; return function { if!iframe { // 创建iframe } return iframe }
}

去掉自执行函数

var test= function{ var iframe; return function { if!iframe { // 创建iframe } return iframe }
} // test每次执行iframe都不一样但是它一次执行的值,肯定是一样的,所以如下:
createFrame = test // createFrame每次执行运行的是test的返回值(函数),它获取的iframe应该是一样的,
// 这个test就和题目中的getSingle作用类似

继续改变使用getSingle

var getSingle = function fn { var result; return function{ // 这个返回函数才是每次执行的函数,result的值在第一次确定之后就不会改变了 return result || result = fn .applythis, arguments ; // 这里又重复了上面提到的概念,result = fn .applythis, arguments, // fn .applythis, arguments每次执行都是不一样的, // 但是result其实获取的某一次执行的值,这个是一样,所以每次获取的其实是同一个值。 }
};

说了这么多其实这个转变最主要的是理解:

var test1 = function { return test
}
test2 = test1 // test1是返回test,test2是执行test函数

每次调用getSingle都会创建result,这个result对于返回的函数来讲是唯一存在的,
var fn = getSingleotherFn
这个fn始终可以访问这个唯一的result,

var fn2 = getSingleotherFn2
这个fn2也包装了一个result

闭包创建了一个返回函数的私有属性罢了

发表评论

电子邮件地址不会被公开。 必填项已用*标注