Entrevista --- js se da cuenta de llamar y aplicar, vincular

Tanto la llamada como la aplicación modifican el método al que apunta esto.
Comencemos con un uso simple.

	var foo = {
    
    
        value: 1
    };
    function bar(name, age) {
    
    
        console.log(name,age,this.value)
    }
    bar.apply(foo,['kevin', 18]);   //kevin 18 1
    
    var foo = {
    
    
        value: 1
    };
    function bar(name, age) {
    
    
        console.log(name,age,this.value)
    }
    bar.call(foo,'kevin', 18); //kevin 18 1

La única diferencia en el uso es pasar parámetros. La llamada debe pasar los parámetros uno por uno, y el parámetro de aplicación se pasa como una matriz.
Implementemos el método de llamada
. Imagina cómo hacer que bar pertenezca a foo. Porque solo cuando bar ingresa a foo, esto apunta a foo
. Los amigos definitivamente pueden pensar en ello, agregar el método a foo y ejecutarlo, y luego eliminarlo después de la ejecución.

Function.prototype.call2 = function(context){
    
    
        context.fn = this;
		context.fn();
        delete context.fn;
 }
//我们在测试一下
	var foo = {
    
    
        value: 1
    };
    function bar() {
    
    
        console.log(this.value);
    }
    bar.call2(foo);   // 1

1 está impreso aquí, y está realizado. ( )
No estés demasiado ansioso por ser feliz, hay otras necesidades que satisfacer.
la llamada se establece de forma predeterminada en ventana cuando no se pasa ningún objeto de destino. También está el caso de llevar parámetros.
Así que vamos a optimizar

	Function.prototype.call2 = function(context){
    
    
        var context = context || window;
        context.fn = this;
        let arr = [];
        for(let i = 1,len = arguments.length; i < len; i++ ){
    
    
            arr.push(arguments[i]);
        }
        context.fn(...arr);
        console.log(context.fn)
        delete context.fn;
    }
	//下面是简化版
	Function.prototype.call3 = function(context){
    
    
		var context = context || window;
		context.fn = this;
		var arr = Array.prototype.slice.call(arguments,1);
		context.fn(...arr);
		delete context.fn;
	}
	
    //下面是测试
    var foo = {
    
    
        value: 1
    };
    function bar(name, age) {
    
    
       console.log(name,age,this.value)
    }
    bar.call2(foo, 'kevin', 18); //kevin 18 1

Primero hicimos un juicio arriba, juzgando si el parámetro de destino existe y no apunta a la ventana.
Obtenga los parámetros pasados ​​en la matriz. Hay otro punto de conocimiento aquí, que son los argumentos. (Aceptar todos los parámetros pasados); ponemos todos los parámetros excepto el primer parámetro en la matriz, y luego lo pasamos al llamar. Mi lado está usando el método es6.
Algunos otros grandes usan eval('context.fn(' + args +')'); esta forma de escribir. Ejecute el método de eliminación.
De esta forma, hemos implementado un método de llamada.
El siguiente es el código para implementar apply, el principio es el mismo y no diré más.

	Function.prototype.apply2 = function(context,arr){
    
    
        var context = context || window;
        context.fn = this;
        context.fn(...arr);
        delete context.fn;
    }
    var foo = {
    
    
        value: 1
    };
    function bar(name, age) {
    
    
        console.log(name)
        console.log(age)
        console.log(this.value);
    }
    bar.apply2(foo,['kevin', 18]); 

La implementación de bind
Echemos un vistazo al uso simple de bind primero.

	let obj = {
    
    
        value:1
    }
    function d(name){
    
    
        console.log(this.value)
        console.log(name);
    }

    var y = d.bind(obj,'lly')
    y() 
    //1
    //lly

Puedes ver arriba que bind devuelve una función y puede aceptar un parámetro.Veamos
cómo lograr esto

	Function.prototype.bind2 = function(context){
    
    
        var self = this;
        var arge = Array.prototype.slice.call(arguments,1);   //取出接受除去第一个的参数数组
        var funone = function(){
    
    
           return self.apply(context,arge)    //通过apply来修改this
        }
        return funone
    }

Del contenido anterior, podemos ver que bind2 devuelve una función y pasa los parámetros aceptados.
bind tiene otra situación para ver el código

	let obj = {
    
    
            value:1
        }
        function d(name,age){
    
    
            console.log(this.value);
            console.log(name)
            console.log(age)
        }

        var y = d.bind2(obj,'lly')
        y(20)   //1 'lly' 20

En el código anterior, podemos ver que este enlace no solo puede pasar parámetros al enlazar, sino también pasar parámetros al llamar.
Esto también es fácil de implementar. Veamos el código.

Function.prototype.bind2 = function(context){
    
    
        var self = this;
        var arge = Array.prototype.slice.call(arguments,1);   //取出接受除去第一个的参数数组
        var funone = function(){
    
    
            let arr = Array.prototype.slice.call(arguments);
           return self.apply(context,arge.concat(arr))    //通过apply来修改this
        }
        return funone
    }

concat (fusionar dos matrices juntas)
podemos ver que solo necesitamos aceptar los parámetros nuevamente al crear la función. Es bueno juntarlo cuando se pasa.
A continuación, veamos otra pieza de código. Otro uso de bind se vuelve a colocar cuando la función se usa como constructor.

		var value = 2;
        let obj = {
    
    
            value:1
        }
        function d(name,age){
    
    
            console.log(this.value)
            console.log(name)
            console.log(age)
        }
        var y = d.bind(obj,'lly');
        let as = new y(20);
        //undefind  lly 20

En este momento, podemos ver que el valor dentro no se puede encontrar En este momento, esto ya no pertenece a obj. Esto es por eso, piensa en lo que hace el proceso de nuevo. (Estudiantes que no saben, échenle un vistazo, hagan clic aquí para echarle un vistazo ) También pueden mirar los mejores escritos de otras personas. Este proceso ya ha apuntado a este objeto de lo nuevo nuevo. Entonces nuestro valor global tampoco se puede encontrar. Tampoco se puede encontrar thisbound by bind. Pero los parámetros pasados ​​todavía están en efecto. Lo siguiente es darse cuenta de la situación cuando se usa el constructor del objeto.

	 Function.prototype.bind2 = function(context){
    
    
        var self = this;
        var arge = Array.prototype.slice.call(arguments,1);   //取出接受除去第一个的参数数组
        let funa = function(){
    
    };
        var funone = function(){
    
    
            let arr = Array.prototype.slice.call(arguments);
           return self.apply(this instanceof self?this:context,arge.concat(arr))    //通过apply来修改this
        }
        funa.prototype = this.prototype;
        funone.prototype = new funa();
        return funone
    }

	

Referencia
https://juejin.cn/post/6844903476477034510#heading-2
https://juejin.cn/post/6844903476623835149

Supongo que te gusta

Origin blog.csdn.net/weixin_44655037/article/details/117127573
Recomendado
Clasificación