js根據字符串調用函數(三種實現方式)

三種方式封裝

1.eval(str)-----eval方法效率低,而且不安全

eval(str) 函數可計算某個字符串,並執行其中的的 JavaScript 代碼。注意,eval方法的參數只能是字符串,如果傳遞的不是字符串的話,會直接返回傳值,而非調用。由於eval方法效率低,而且不安全,不建議使用。

function test(str){
    alert(str);
}
var a='test';
var b='345';
eval(a+'('+123+')');
eval(a+'(b)');

  1. 函數在js裏面可以被保存在對象中,因此通過對象的屬性訪問,調用字符串方法。
    –(我就是根據這個封裝的)

1.全局函數聲明和全局變量會變成全局對象的屬性。全局對象在進入執行上下文前創建的一個唯一的對象。在瀏覽器運行環境裏,全局對象就是window對象
2.屬性訪問可以使用 點標記法 或者括號標記法。其中使用點訪問需要標識符,二括號訪問使用的是標識符對應的字符串

function test(str){
    alert(str);
}
 
var param='哈哈';
window['test'](param);//直接執行
window['test'].call(this,'param');

  1. 和2一樣,不過全部集成在一個對象中,每次訪問的時候,都調用這個對象的對象的方法

封裝函數

依賴 underscore.js
代碼

	//模擬js 通過字符串執行函數
	_.mixin({
		/**基於字符串獲取 函數名稱和參數對象 //不準持有無效的引號
		 * 示例  test(1,5,6,7);
		 * @params str  字符串函數
		 * 
		 */
		getFunctionObj: function(str) {

			var functionObj = {
				functionName: "",
				functionParams: []
			}
			if(_.isString(str)) {
				if(str.indexOf("(") != -1 && str.indexOf(")") != -1) {
					var arr = str.split("(");
					functionObj.functionName = arr[0];
					arr = arr[1].split(")");
					if(!_.isEmpty(arr[0])) {
						functionObj.functionParams = arr[0].split(",");
					}
				} else { //兼容未命名() 的函數
					functionObj.functionName = str;
				}
			}
			return functionObj;
		},
		/* 基於字符串獲取當前window的對象函數對象
		 * @params str  字符串函數
		 * @parmas  falg   默認false,
		 * true 立即調用這個函數,false 返回函數對象及其函數參數
		 */
		getFunction: function(str, falg) {
			if(_.isString(str)) {
				var functionObj = _.getFunctionObj(str);
				var strFunction = functionObj.functionName;
				if(!_.isEmpty(strFunction)) {
					var arr = strFunction.split(".");
					strFunction = window[arr[0]];
					for(var i = 1, len = arr.length; i < len; i++) {
						if(!strFunction && !_.isFunction(strFunction) && !_.isObject(strFunction)) {
							return null;
						}
						strFunction = strFunction[arr[i]];
					}
					if(_.isFunction(strFunction)) {
						if(falg) {
							strFunction.apply(strFunction, functionObj.functionParams); //測試是否是方法可以測試出來
						}
						functionObj.fun = strFunction;
						return functionObj;
					}
				}
				return null;
			}
			return str;
		}
	});

調用方式

true 爲 立即執行, false爲 獲取函數對象,自己手動執行
手動執行
	 var obj =  _.getFunction("test",false); //fasle可以不填
	 _.exeFunction(obj);

1.支持默認全局函數調用

//測試全局函數
			function test() {
				alert("test");
			}
	_.getFunction("test",true);

2.支持對象函數調用

			//測試對象函數
			var obj = {
				test: function() {
					alert("obj.test");
				}
			}
			_.getFunction("obj.test",true);

3.支持jquery插件函數調用

			//測試jquery插件函數
			;(function($) {
				$.extend({
					lay: {
						alert: function() {
							alert("$");
						}
					}
				})
			})(jQuery, undefined);
			_.getFunction("$.lay.alert",true);

4.支持基礎全局函數含簡單參數使用

			//測試基礎函數參數
			function test2(a, b, c) {
				console.log("arr" + a + b + c);
				alert("test2" + a + b + c);
			}
				_.getFunction("test2(1,2,3);",true);

不支持

//局部變量函數
		  var  test12 = function(){
		  	alert(test12);
		  }
		  _.getFunction("test12();",true);
			//測試複雜函數參數
			var a = $(document);
			_.getFunction("test2("+a+",2,3);",true);
			//

單元測試

	//寫好單元測試 
			//測試全局函數
			function test() {
				alert("test");
			}
			 _.getFunction("test",true);
			 	//測試手動執行
			 var obj =  _.getFunction("test",false); //fasle可以不填
			 _.exeFunction(obj);
		
			//測試對象函數
			var obj = {
				test: function() {
					alert("obj.test");
				}
			}
			_.getFunction("obj.test",true);
			//測試jquery插件函數
			;(function($) {
				$.extend({
					lay: {
						alert: function() {
							alert("$");
						}
					}
				})
			})(jQuery, undefined);
			_.getFunction("$.lay.alert",true);
			//測試基礎函數參數
			function test2(a, b, c) {
				console.log("arr" + a + b + c);
				alert("test2" + a + b + c);
			}
				_.getFunction("test2(1,2,3);",true);
		  //以下不支持的
		  //局部變量函數
		  var  test12 = function(){
		  	alert(test12);
		  }
		  _.getFunction("test12();",true);
			//測試複雜函數參數
			var a = $(document);
			_.getFunction("test2("+a+",2,3);",true);
			//
								

		
			//test.apply(null);				

參考博客

https://blog.csdn.net/xingmeiok/article/details/82901068

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章