jca*_*ddy 0 javascript closures
作为一个相当新的Javascript和ac#背景我一直在磕磕绊绊.我很快就知道,我需要了解函数本身就是对象这一事实,而且JS闭包通常是导致混淆的原因.
我试图理解这段代码
// Function which returns object with function properties
function myFunc() {
value = 42;
var result = {
value: value,
getValue: getValue,
incrementValue: incrementValue,
setValue: setValue,
};
return result;
function setValue(y) {
value = y;
};
function getValue() {
return value;
};
function incrementValue() {
value++;
};
};
// Helper function to print out results
function printResults(m,x){
$('#output').append(m + ': ' + x).append('<br/>');
};
var myObject = myFunc(); // returns the object
printResults('Inital call to getValue',myObject.getValue());
myObject.setValue(59);
printResults('Called changeValue',myObject.getValue());
printResults('Value property of object',myObject.value);
printResults('Called getValue again',myObject.getValue());
myObject.incrementValue();
printResults('Call increment value',myObject.getValue());
printResults('Value property of object',myObject.value);
Run Code Online (Sandbox Code Playgroud)
在jsFiddle中运行时,我得到以下结果
Inital call to getValue: 42
Called changeValue: 59
Value property of object: 42
Called getValue again: 59
Call increment value: 60
Value property of object: 42
Run Code Online (Sandbox Code Playgroud)
这些表明函数value在它们的闭包中使用变量,并且这在内部函数的调用之间持续存在.但是,value返回的对象中的值不会改变.
我想我得到的函数是使用在定义时生效的作用域链来执行的基本点.
问题
我是否可以使value返回对象的属性以相同的方式运行 - 或者是通过函数返回它的唯一方法,因为后者在其闭包中保留变量?
并且,为了确认,对于每次调用myFunc(),我假设我将获得一个对象,其函数属性将具有自己的作用域链,因此独立于每次调用.
首先,var在声明变量时不要忘记关键字.在value = 42内部声明时myFunc,实际上是在全局命名空间而不是函数范围中创建变量.它应该像这样开始:
function myFunc() {
var value = 42;
Run Code Online (Sandbox Code Playgroud)
现在,myObject.result返回42是因为myFunc返回result包含value函数内声明的变量副本的对象.
你的功能setValue,getValue和incrementValue正在改变的价值value,不是result.value.当您调用时myObject.value,您将从返回的对象获取值,而不是函数的内部变量.
你可以使用这样的东西让它工作:
function myFunc() {
var value = 42;
var result = {
value: value,
getValue: getValue,
incrementValue: incrementValue,
setValue: setValue
};
return result;
function setValue(y) {
result.value = y;
}
function getValue() {
return result.value;
}
function incrementValue() {
result.value++;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,有比这更好的设计模式.您可以使用new关键字并prototype定义可用于从函数返回的对象的方法.举个例子:
function myFunc() {
this.value = 42;
}
myFunc.prototype.setValue = function(y) {
this.value = y;
}
myFunc.prototype.getValue = function(y) {
return this.value;
}
myFunc.prototype.incrementValue = function(y) {
this.value++;
}
var myObject = new myFunc();
console.log(myObject.getValue()); // 42
myObject.setValue(30);
myObject.incrementValue();
console.log(myObject.getValue()); // 31
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
861 次 |
| 最近记录: |