【问题标题】:How to override closure variables in JavaScript?如何覆盖 JavaScript 中的闭包变量?
【发布时间】:2019-01-05 19:50:13
【问题描述】:

闭包是函数和声明该函数的词法环境的组合。

但是由于闭包环境中定义的私有变量没有被外部范围覆盖。

但我仍然想覆盖闭包变量。怎么可能?

(function() {

    var foo = 'Hello John';

    function baz(){
        return foo;
    }
})();

现在将变量 foo 的值覆盖为其他内容,例如 Good Morning

【问题讨论】:

  • 在给予声誉之前请检查以下代码。
  • 你的意思是分享你的知识。这更像是一个社区维基而不是一个问题。谢谢!

标签: javascript variables scope closures overriding


【解决方案1】:

如何覆盖 JavaScript 闭包变量?

由于闭包变量具有私有范围,并且在其范围之外无法访问。

但是我们可以设置和获取闭包变量。请参阅下面的示例,它可以帮助您解决问题。

let code = (function($){

	function var_export (mixedExpression, boolReturn) {
		var echo = console.log;
		var retstr = ''
		var iret = ''
		var value
		var cnt = 0
		var x = []
		var i = 0
		var funcParts = []
		// We use the last argument (not part of PHP) to pass in
		// our indentation level
		var idtLevel = arguments[2] || 2
		var innerIndent = ''
		var outerIndent = ''
		var getFuncName = function (fn) {
			var name = (/\W*function\s+([\w$]+)\s*\(/).exec(fn)
			if (!name) {
				return '(Anonymous)'
			}
			return name[1]
		}
		var _makeIndent = function (idtLevel) {
			return (new Array(idtLevel + 1))
			.join(' ')
		}
		var __getType = function (inp) {
			var i = 0
			var match
			var types
			var cons
			var type = typeof inp
			if (type === 'object' && (inp && inp.constructor) &&
				getFuncName(inp.constructor) === 'LOCUTUS_Resource') {
				return 'resource'
			}
			if (type === 'function') {
				return 'function'
			}
			if (type === 'object' && !inp) {
			// Should this be just null?
			return 'null'
			}
			if (type === 'object') {
				if (!inp.constructor) {
					return 'object'
				}
				cons = inp.constructor.toString()
				match = cons.match(/(\w+)\(/)
				if (match) {
					cons = match[1].toLowerCase()
				}
				types = ['boolean', 'number', 'string', 'array']
				for (i = 0; i < types.length; i++) {
					if (cons === types[i]) {
						type = types[i]
						break
					}
				}
			}
			return type
		}
		var type = __getType(mixedExpression)
		if (type === null) {
			retstr = 'NULL'
		} else if (type === 'array') {
			outerIndent = _makeIndent(idtLevel - 2)
			innerIndent = _makeIndent(idtLevel)
			for (i in mixedExpression) {
				value = var_export(mixedExpression[i], 1, idtLevel + 2)
				value = typeof value === 'string' ? value.replace(/</g, '&lt;')
				.replace(/>/g, '&gt;') : value
				x[cnt++] = value
			}
			iret = x.join(',');
			retstr = '[' + iret +']';
		} else if (type === 'object') {
			outerIndent = _makeIndent(idtLevel - 2)
			innerIndent = _makeIndent(idtLevel)
			for (i in mixedExpression) {
				value = var_export(mixedExpression[i], 1, idtLevel + 2)
				value = typeof value === 'string' ? value.replace(/</g, '&lt;')
				.replace(/>/g, '&gt;') : value
				x[cnt++] = i + ':' + value;
			}
			iret = x.join(',')
			retstr = '{' + iret + '}'
		} else if (type === 'function') {
			funcParts = mixedExpression.toString().match(/function .*?\((.*?)\) \{([\s\S]*)\}/)

			retstr = "create_function ('" + funcParts[1] + "', '" +
			funcParts[2].replace(new RegExp("'", 'g'), "\\'") + "')"
		} else if (type === 'resource') {
		// Resources treated as null for var_export
		retstr = 'NULL'
		} else {
			retstr = typeof mixedExpression !== 'string' ? mixedExpression
			: "'" + mixedExpression.replace(/(["'])/g, '\\$1').replace(/\0/g, '\\0') + "'"
		}
		if (!boolReturn) {
			echo(retstr)
			return null
		}
		return retstr
	}
	var settings = {
		name: 'Hello John',
		code: 'CODE12345',
		location: 'US'
	};	
	return{
		getSettings : function(name){
			console.log('Access closure variables: ',eval(name));
		},
		setSettings: function(name, value){
			console.log('Set closure variables.', eval(name+'='+(var_export(value, true))));
		}
	}
})();

//1. Check settings before overriding
code.getSettings('settings');
//2. To set settings (override existing closure variable):
code.setSettings('settings',{
		name: 'CoreX',
		code: 'HACK9876',
		location: 'Unknown'
	}
);
//3. To access new seetings:
code.getSettings('settings');

【讨论】:

  • 为什么不 -> return {settings: settings};?你想做什么,。也使用eval 通常不受欢迎。
  • 我知道但仍想设置以前已经具有旧值的新闭包变量。每个代码都有一个循环孔,所以这是其中之一。
  • 当您尝试在用 JavaScript 开发的现成项目中创建自定义钩子时,会使用此类代码。那时需要覆盖一些默认变量,因为您不需要旧值。
猜你喜欢
  • 2010-11-29
  • 2015-07-04
  • 2016-12-05
  • 1970-01-01
  • 2023-03-15
  • 2015-03-13
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
相关资源
最近更新 更多