Heim >Web-Frontend >js-Tutorial >js-Funktionsrückruf

js-Funktionsrückruf

(*-*)浩
(*-*)浩nach vorne
2019-08-06 16:35:413177Durchsuche

In der normalen Front-End-Entwicklungsarbeit werden beim Schreiben von js an vielen Stellen Funktionsrückrufe verwendet.

Das einfachste Beispiel ist:

<script language="javascript" type="text/javascript">
function doSomething(callback) {
if(typeof callback == "function") {
callback();
}
} 
 
function foo() {
alert("我是回调后执行的函数");
} 
 
doSomething(foo); /*正确*/
doSomething(function(){
alert("我是回调后执行的函数");
}); /*正确*/
doSomething("foo"); /* 这样是不行的,传入的是一个字符串,不是一个函数名 */
</script>

Das Obige kann nur ohne Parameter zurückrufen (es sei denn, Sie kennen die Parameter der Rückruffunktion im Voraus). Wenn die Funktion unbekannte Funktionen hat, kann dies nicht der Fall sein einfach.

Erweiterte Methoden:

1. Verwenden Sie die Aufrufmethode von Javascript

function doSomething(callback,arg1,arg2) {
callback.call(this,arg1,arg2);
}
function foo(arg1,arg2) {
alert(arg1+":"+arg2);
}
doSomething(foo,1,2); /* 弹出了1:2 */

2. Verwenden Sie die Apply-Methode von Javascript

betrachtet als call Es ist im Grunde dasselbe wie apply. Der Unterschied besteht darin, dass call Parameter nur einzeln übergeben kann und apply nur Parameter in einem Array übergeben kann.

Ihre ersten Parameter sind alle Bereiche. Wenn dies beispielsweise oben übergeben wird, bedeutet dies, dass es den gleichen Bereich wie die Funktion „doSomething“ hat. also den gesamten Fensterbereich.

3. Clevere Verwendung von apply

apply kann auch als Ausführungsfunktion einer Funktion betrachtet werden, bei der es sich um eine Funktion handelt, die zum Ausführen einer bestimmten Funktion verwendet wird. Sie werden also feststellen, dass viele Dinge, die ursprünglich kompliziert waren, manchmal so einfach werden, wenn Sie „Apply“ richtig anwenden.

Zum Beispiel wird die Push-Methode eines Arrays mit apply aufgerufen:

var arr1=[1,3,4];

var arr2=[3,4 ,5];

Wenn wir arr2 erweitern und dann nacheinander an arr1 anhängen möchten, sei schließlich arr1=[1,3,4,3,4,5]

arr1 .push(arr2 ) ist offensichtlich nicht möglich. Denn wenn Sie dies tun, erhalten Sie [1,3,4,[3,4,5]]

Wir können eine Schleife nur verwenden, um einen nach dem anderen zu pushen (natürlich können Sie auch arr1.concat(arr2) verwenden. , aber die Concat-Methode ändert arr1 selbst nicht)

function doSomething(callback,args) {
callback.apply(window,args);
}
function foo(arg1,arg2) {
alert(arg1+":"+arg2);
}
doSomething(foo,[1,2,3]); /* 弹出了1:2 */
Seit es Apply gibt, sind die Dinge so einfach geworden

Array.prototype.push.apply(arr1, arr2)

Eine Codezeile löst das Problem. Das Prinzip ist, dass Array.prototype.push die Push-Funktion des Arrays ist, die angibt, dass arr1 der Bereich ist, der dem Aufruf von arr1 entspricht Push-Funktion des Arrays.

Und arr1 ist tatsächlich ein Array, also kann es aufgerufen werden, und arr2 repräsentiert das Array von Parametern. Daher entspricht die obige Anweisung: arr1.push(3,4,5). (

Die Push-Funktion unterstützt die Übergabe mehrerer Eingabeparameter, was auch eine Voraussetzung für die Verwendung von apply hier ist)

Die obige Anweisung kann auch geschrieben werden als: arr1.push.apply(arr1, arr2 ); Beide Die beiden sind völlig gleichwertig, da arr1.push die Push-Funktion von arr1 darstellt, die die Push-Funktion des Arrays ist.

Wenn Sie call verwenden, ist es wie Array.prototype.push.call(arr1, arr2[0], arr2[1]...), offensichtlich ist es immer noch angemessen, es anzuwenden.

Wenn Sie immer noch fragen, warum verwenden Sie nicht einfach arr1.push(3,4,5)? Es ist nicht so, dass arr2 beim nächsten Mal nicht geändert werden kann [3,4,5].

Um die größte Zahl im Array zu erhalten, können Sie auch Apply verwenden, um die Math.max-Funktion

var arr1=[1,3,4];

aufzurufen Alert (Math.max.apply(window,arr1)); /* Der Bereich muss kein Fenster sein, auch wenn er null ist, Math.max.apply(this,arr1), Math.max.apply(null, arr1) */

4. Praktische Beispiele für Funktionsrückrufe bei der Arbeit

Mit der oben genannten Grundlage können Sie die gekapselten JS-Rückruffunktionen bei der Arbeit verstehen

Hintergrund: Seite A muss Seite B verwenden, um ein Element auszuwählen, und bringt dann die Informationen zu diesem Element auf Seite A zurück. Seite A bereichert sich anhand dieser Informationen.

Seite A:

var arrLen=arr2.length
for(var i=0;i<arrLen;i++){
    arr1.push(arr2[i]);
}

Seite B:

noticeInfo = {
selectProject: function () {
var win = newsee.ui.window
win.show(&#39;项目列表&#39;, &#39;../Project/ProjectSelectList.html?callback=noticeInfo.setProjectInfo&#39;, { size: win.winSizeType.big })
//在当前页面弹出框,框里面是另一个页面,地址后面带上需要回调的函数名
//注意这两个页面其实都是在一个页面里面的,并不是像window.open()那样出现了新窗口,所以两个页面的js都是可见的
},
setProjectInfo: function (obj) {
//回调函数,将选择好的项目对象传进来,然后丰富自己的页面
$(&#39;#projectName&#39;).val(obj.name)
$(&#39;#projectID&#39;).val(obj.id)
}
}

newsee.util.url.back-Funktion ist wie folgt:

function SelectBack() {
var callback = newsee.util.url.getQuery(&#39;callback&#39;); //获取页面参数callback,这里获取到的是"noticeInfo.setProjectInfo",是个字符串
var arr = newsee.ui.grid.getSelectedBack(&#39;datagrid&#39;) //获取选择的项目,这个不用深究
if (!arr.length) {
return newsee.ui.window.alert(&#39;请选择项目!&#39;)
}
newsee.util.url.back(callback, arr[0]) //重点来了,这里执行回调,将需要回调的函数名和入参传进来,arr[0]就是选择的项目的对象的数组了(它也是个数组,里面就一个对象)
}

newsee.callFunc-Funktion ist wie folgt:

back : function (funcName) {
// / <param name="funcName" type="String">返回时执行的方法,一般为重新绑定</param>
 
var isWindow = typeof $$winClose === 'function',// 是否为弹窗
args // 弹窗返回方法参数
 
if (isWindow) {// 弹窗的返回方法
$$winClose()
 
args = [].slice.call(arguments) //arguments大家应该都知道的吧,它可以用来获取函数的实参,它类似数组又不是数组,这句代码就是把它转换成数组,因为apply的入参需要是个数组才行
//args现在里面有两个元素,args[0]=callback,就是之前传进来的回调函数名,args[1]=arr[0],就是回调函数的入参
newsee.callFunc.apply(newsee, args) //执行 newsee.callFunc 函数,作用域就是newsee自己(等同于newsee自己调用callFunc函数),参数是args
} 
}
ok, die Funktion, die zurückgerufen werden muss, wird ausgeführt. Informationen zum Abrufen dieser Funktion basierend auf dem Funktionsnamen in Zeichenfolgenform finden Sie unten.

callFunc: function(funcName, arg) {
var func = typeof funcName === 'function' ? funcName : this.findItem(window, funcName) //上面我有提到过,doSomething("foo"); 传入的是一个字符串,不是一个函数名,所以无法执行
//同样的道理,现在funcName=args[0]=callback="noticeInfo.setProjectInfo",是个字符串,不能直接调用apply,需要变成函数
//这句话就是用来判断funcName是不是一个函数,如果不是,就在window作用域里根据funcName找到这个函数,然后赋给func
if (typeof func === 'function') {
//此时func已经是个函数了,就是页面A里定义的noticeInfo.setProjectInfo()
try {
return func.apply(window, arg) //执行需回调的函数,作用域依然是window,反正这个函数在window里肯定能找到,参数就是arg=args[1]=arr[0],即之前在页面B获取到的项目对象
}
catch (e) {
console.error(e)
}
}
}
Führen Sie außerdem die Funktion eval() ein:

Die Funktion eval() kann eine bestimmte Zeichenfolge berechnen und den darin enthaltenen JavaScript-Code ausführen.

Der Rückgabewert ist der Wert, der durch die Berechnung der Zeichenfolge (falls vorhanden) erhalten wird. Zum Beispiel:

//findItem函数如下:
findItem: function(data, key) {
// / <summary>获取对象指定键的值</summary>
if (this.include(data, key)) { //data这里就是传进来的window,注意window就是一个对象,首先判断window对象里是否存在"noticeInfo.setProjectInfo"这个属性
return eval('data.' + key) //如果存在,就执行"data.noticeInfo.setProjectInfo",这样就获取到了这个函数了。(eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码)
}
}
//include函数如下:
include: function(data, key) {
// / <summary>判断对象是否存在键值</summary>
if (data == null || typeof data !== 'object' || !key || typeof key !== 'string') {
return false
}
var keys = key.split('.'),
item = data,
result = true
keys.forEach(function(k) {
if (item != null && typeof item === 'object' && k in item) {
//依次循环遍历,第一次item = data,那就是window这个对象,k="noticeInfo",window[noticeInfo]是存在的,因为在页面A里定义了noticeInfo这么一个对象
//第二次循环,item=window.noticeInfo,k="setProjectInfo",window.noticeInfo[setProjectInfo]也是存在的,因为在页面A里也定义了setProjectInfo这么一个函数
//这里没有第三次循环了,所以最后返回是true,说明window对象里存在"noticeInfo.setProjectInfo"这个属性,接下来使用eval()拿到它即可
item = item[k]
} else {
return result = false
}
})
 
return result
}
Das obige eval('data.' + key) dient also dazu, die Zeichenfolge "data.noticeInfo.setProjectInfo" auszuführen,

Weil sich die Daten hier auf das Fenster beziehen, also es gibt zurück Der Wert ist die Funktion window.noticeInfo.setProjectInfo()

Tatsächlich kann es einfacher sein, eval() zu verwenden, um diese Funktion abzurufen, da das Element in der Include-Funktion enthalten ist bereits window.noticeInfo.setProjectInfo Dieses Objekt ist die Funktion, die wir wollen.

(

In js sind Funktionen auch Objekte. Der Funktionsname ist ein Verweis auf diese Funktion, der fast mit der Adresse identisch ist)

Seitdem haben wir Diese Funktion können wir nicht direkt zurückgeben. Daher können die obigen Methoden include() und findItem wie folgt vereinfacht werden:

eval("x=10;y=20;document.write(x*y)") //输出 200
document.write(eval("2+2")) //输出 4
var x=10
document.write(eval(x+17)) //输出 27
Nach dem Testen wurde festgestellt, dass diese beiden Methoden zum Abrufen von Funktionen darauf basieren Funktionsnamen in Stringform können genau den gleichen Effekt erzielen.

Das obige ist der detaillierte Inhalt vonjs-Funktionsrückruf. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen