Grundlegende JavaScript-Lernmethode für das Front-End (2)

一 、 aufrufen, anwenden, binden

call, apply, bind werden alle verwendet, um diesen Punkt zu ändern

der Unterschied:

Verschiedene Parameter

Passparameter in durch Kommas getrennter Form aufrufen

Funktionsname.call (Zielobjekt, Parameter 1, Parameter 2, ... Parameter n)

Zum Beispiel: getName.call (obj, '王 五', 25, 'Beijing')

Apply-Parameter werden in Form eines Arrays übergeben

Funktionsname.apply (Zielobjekt, [Parameter 1, Parameter 2, ... Parameter n])
Zum Beispiel: getName.apply (obj, ['王 五 11', 25, 'Shanghai'])

Bind verwendet Kommas, um Parameter zu übergeben

Ob die Funktion getName.bind (obj, '王 五 11', 25, 'Shanghai') () oder getName.bind (obj) ('王 五 11', 25, 'Shanghai')
ausgeführt wird

cal und apply direkt aufrufen Die Funktion
bind soll die Funktion selbst zurückgeben. Wenn Sie ausführen möchten, müssen Sie add () aufrufen,
getName.bind (obj) ()
aufrufen und das Implementierungsprinzip anwenden

Das Realisierungsprinzip des Anrufs (kein Anruf erforderlich, manuelle Simulation der Funktion eines Anrufs)

call是基于函数实现的
给作用的目标对象添加一个临时函数,处理赋值操作
接收参数处理
最后再删除这个临时函数
实例化对象=new 构造函数() //其中构造函数也称为类,一个类可以生成多个实例化对象

var f1=new Function() // 其中的构造函数中this===f1 永远相等
var p1=new Person() //其中的构造函数中this===p1 永远相等
//call模拟实现原理代码:
Function.prototype.call2 = function (context) {
    
    
    //目标对象
    context = context || window;

    //this===实例化的函数,函数本质上也是对象

    //给context添加一个临时函数
    context.fn = this;

    //接收参数处理  arguments
    console.log('arguments:',arguments)
    var args = [];
    for (var i = 1; i < arguments.length; i++) {
    
    

       // ["arguments[0]", "arguments[1]", "arguments[2]"]
        args.push('arguments['+i+']')
       // args.push(arguments[i])
    }

     //传参执行context.fn()函数
     eval('context.fn(' + args + ')')
    
    
    //删除临时函数
    delete context.fn

    
}

Implementierungsprinzip anwenden
Function.prototype.apply2 = function (context, arr) { // Zielobjekt context = context || window;

//this===实例化的函数,函数本质上也是对象

//给context添加一个临时函数
context.fn = this;

if (!arr) {
    context.fn()
} else {
    //接收参数处理  arguments
    var args = [];
    for (var i = 0; i < arr.length; i++) {

    // ["arguments[0]", "arguments[1]", "arguments[2]"]
        args.push('arr['+i+']')
    // args.push(arguments[i])
    }

    //传参执行context.fn()函数
    eval('context.fn(' + args + ')')


 }

//删除临时函数
delete context.fn

}}

Implementierungsprinzip binden

var obj = {
    
    
    init: 1,
    add: function(a, b) {
    
    
        return a + b + this.init;
    }
}
obj.add(1, 2); // 4
 
var plus = obj.add;
plus(3, 4); // NaN,因为 this.init 不存在,这里的 this 指向 window/global
 
plus.call(obj, 3, 4) // 8
plus.apply(obj, [3, 4]); // 8, apply 和 call 的区别就是第二个参数为数组
plus.bind(obj, 3, 4); // 返回一个函数,这里就是 bind 和 call/apply 的区别之一,bind 的时候不会立即执行

Die Zusammenfassung
besteht einfach darin, bind zu verwenden, um diesen Punkt zu ändern. Der Unterschied zwischen call / apply hat einen verzögerten Ausführungseffekt

Zweitens das Realisierungsprinzip des Neuen

Funktionen von neu

  1. Wenn ein neuer Konstruktor ein instanziiertes Objekt automatisch neu erstellt
  2. Das neue instanziierte Objekt __proto___ zeigt automatisch auf den Prototyp des Konstruktors
  3. Der neue Konstruktor übergibt Parameter und weist dem aktuell instanziierten Objekt automatisch Werte zu

Drei, Anti-Shake und Drosselung

Anti-Shake-Konzept

Wenn es zu einer festgelegten Zeit kein Auslöseereignis gibt, wird es nach Ablauf der festgelegten Zeit ausgelöst. Wenn das Ereignis innerhalb einer festgelegten Zeit ausgelöst wird, wird es nach einer festgelegten Zeit erneut ausgelöst. Das
Anti-Shake wird hauptsächlich durch den Timer realisiert

//用定时器实现防抖
function debounce(func,wait) {
    
    
    var timer=null;
    return function() {
    
    
    //保存当前调用的dom对象
     var _this=this;
     //保存事件对象
     var args=arguments;
     clearTimeout(timer)
     timer=setTimeout(function() {
    
    
         func.apply(_this,args)
     },wait)
    }

}

Drosselungskonzept:

Unabhängig davon, ob ein Ereignis innerhalb einer festgelegten Zeit ausgelöst wird, wird es gemäß der festen Zeitregel ausgelöst

Es gibt zwei Methoden für die spezifische Implementierung

Der erste Typ: Zeitstempel

//时间戳版本实现节流
function throttle(func,wait) {
    
    
    //定义初始时间
    var oldTime=0;

    return function() {
    
    
        var _this=this;
        var args=arguments;

        //当前时间戳
        var newTime=+new Date();

        //判断用当前时间减去旧的时间,如果大于wait指定的时间就会触发
        if(newTime-oldTime>wait) {
    
    
            //执行触发的函数
            func.apply(_this,args)
            //将旧时间更新
            oldTime=newTime;
        }

    }

Der zweite Typ: Timer

//时间戳版本实现节流
function throttle(func,wait) {
    
    
    var timer=null;

    return function() {
    
    
        var _this=this;
        var args=arguments;
       if(!timer) {
    
    
            timer=setTimeout(function() {
    
    
                timer=null;
                func.apply(_this,args)
            },wait)
       }
    }
}

Wenn Sie sich mit den oben genannten Themen nicht auskennen, können Sie natürlich die aktuelle Mainstream-Tool-Bibliothek verwenden: lodash hat eine umfassende Tool-Methode bereitgestellt

Weitere Informationen finden Sie auf der Website von lodash: https://www.lodashjs.com/

Ich denke du magst

Origin blog.csdn.net/weixin_48193717/article/details/108328759
Empfohlen
Rangfolge