一 、 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
- Wenn ein neuer Konstruktor ein instanziiertes Objekt automatisch neu erstellt
- Das neue instanziierte Objekt __proto___ zeigt automatisch auf den Prototyp des Konstruktors
- 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/