js中的偷天换日

1.定义一个function A(data), 将此作为参数传入另外一个function B并在B其中修改 A的参数

比如这里定义A

 var A = function(data){
            alert(data);
        };

定义B

function B(func){
            $.ajax({
                type: "GET",
                url: "http://localhost:8080/getJson/nihao",
                success: func,
                error:function(err){

                }
            });
        }
<button onclick="B(A)" type="button">点击</button>

这样调用B(A)则会正常弹出alert,值为data,但是如果我想在执行A之前对success的返回值做做手脚,比如将他的字符串更改一下,比如像下面这样改写

        function B(func){
            $.ajax({
                type: "GET",
                url: "http://localhost:8080/getJson/nihao",
                success: function (data) {
                    data = data+" do somthing";
                    func(data);
                },
                error:function(err){

                }
            });
        }

将data拼接字符串后在执行func(data),这个地方比较奇怪,func是B的传入参数,func是一个function在这里我们传入A,但是在success中我却能执行func(data),实际上执行的是A(data),这是个比较有意思的机制。试运行一下发现能正常弹出alert,值为nihao do somthing。这里其实我的理解就是在success中将func重新定义了一下,data参数使用处理过之后的data,但是如果按照对象的观点来看的话,此时的A应该还是之前的function。这里只是使用了A的一个变型。

2.使用function的tostring()方法获取function的字符串值,并做一些小操作

A保持不变,重新定义B

        var A = function(data){
            alert(data);
        };
        function B(func){
            var str = "("+func.toString().replace(/[\r\n]/g,"").replace("data","change(data)")+")";
            var newFunc = eval(str);
            debugger;
            $.ajax({
                type: "GET",
                url: "http://localhost:8080/getJson/你好世界",
                success: newFunc,
                error:function(err){
                }
            });
        }
        function change(v) {
            return  encodeURI(v);//编码
        }

eval(”(执行的内容)”);加上圆括号的目的是迫使eval函数在运行JavaScript代码的时候强制将括号内的表达式转化为对象,而不是作为语句(statement)来执行。将传入的function从开头到结束间的所有字符包括注释。这里将B的参数func转成字符串,去除回车换行符并将“data”替换为“change(data)”,此时理论上我们得到的str应该是

(function(change(data)){    alert(data);   })

此时str为字符串形式,使用eval将其转化为function对象并使用newFunc进行引用,然后此时success的返回方法应该是这样的

function(change(data)){
    alert(data);  
 }

但是实际使用过程中,在eval环节会报Uncaught SyntaxError: Unexpected token '('  只能在replace环节修改函数体内部的内容比如

var A = function(data){
            alert(data);
        };
        function B(func){
            var str = "("+func.toString().replace(/[\r\n]/g,"").replace("alert(data)","alert(change(data))")+")";
            var newFunc = eval(str);
            var str1 = newFunc.toString();
            debugger;
            $.ajax({
                type: "GET",
                url: "http://localhost:8080/getJson/你好世界",
                success: function(data){
                    newFunc(data);
                },
                error:function(err){
                }
            });
        }
        function change(v) {
            return  encodeURI(v);//编码
        }

这样可以正常弹出并显示编码后的内容,change被成功调用。

posted @ 2020-04-25 16:51  DreamCatt  阅读(134)  评论(0)    收藏  举报