为什么闭包函数不能保护对象的值,但裸函数会保留?

时间:2014-03-07 01:17:20

标签: javascript closures lodash

为什么闭包函数不能保护对象的值,但裸函数会保护? I have the below code on jsFiddle

我正在使用默认_.assign的Lo-Dash Object函数。像这样:

var cnst = _.constant({test: 'It Works!'})
var newCnst = _.assign(cnst(), {test: "It doesn't work!"})
console.log(cnst())
console.log(newCnst)

结果是:

{test: "It doesn't work!"}
{test: "It doesn't work!"}

所以我只是做一个像这样的裸体常数函数:

var test = function(){return {test: 'It Works!'}}
var newTest = _.assign(test(), {test: "It doesn't work!"})
console.log(test())
console.log(newTest)

结果是:

{test: 'It Works!'}
{test: "It doesn't work!"}

就像它应该的那样。为什么关闭的常数值不受保护?即使我自己这样做了:

var constant = function(value){return function(){return value}}
var t = constant({test: 'Closured Works!'})
var t2 = _.assign(t(), {test: "No closured doesn't work!"})
console.log(t())
console.log(t2)

结果是:

{test: "No closured doesn't work!"}
{test: "No closured doesn't work!"}

1 个答案:

答案 0 :(得分:1)

原因是在Lo-Dash示例和自定义constant实现中,创建的函数始终返回对相同实例的引用。也就是说,在这两个片段中只创建了一个对象:

var cnst = _.constant({test: 'It Works!'})

var constant = function(value){return function(){return value}}
var t = constant({test: 'Closured Works!'})

这可以通过检查确认:

console.log(newCnst === cnst()) // true
console.log(t2 === t())         // true

但是,在这个例子中:

var test = function(){return {test: 'It Works!'}}

每次调用函数时都会创建一个新对象。所以当你打电话时:

var newTest = _.assign(test() /* new object created here */, {test: "It doesn't work!"})
console.log(test() /* new object created here */)
console.log(newTest)

这可以通过检查确认:

console.log(newTest === test()) // false