O uso de ligar e aplicar - ramal

1. Revisão

No artigo anterior sobre o uso de call and apply - o básico , já mencionamos as funções e sintaxe de call and apply, aqui vai uma breve revisão:

Introdução: call e apply são métodos de função, que precisam ser adicionados após o corpo da função para serem executados.

Função: Ambos são usados ​​para modificar o contexto de execução (this) da função.

gramática:

  • chamar(esteObj,arg1,arg2,arg3,......)
  • apply(thisObj, argArr)
    descrição: A principal diferença entre call e apply é: call pode aceitar um ou mais parâmetros. Quando vários parâmetros são aceitos, a partir do segundo parâmetro, todos os parâmetros subsequentes alterarão os parâmetros da função original; apply só pode aceitar um ou dois parâmetros. Quando aceita dois parâmetros, o segundo parâmetro deve ser uma matriz ou matriz de classe. Os dados na matriz alterarão os parâmetros nos argumentos da função original.
    Os primeiros parâmetros de call e apply são usados ​​para alterar o ponto this da função original.

Portanto, a demonstração a seguir é baseada principalmente em chamada. Se houver apenas um parâmetro, ele pode ser substituído diretamente por apply, e não há diferença; se houver mais de dois parâmetros, ao substituí-lo por apply, o segundo e todos os parâmetros subsequentes precisam ser colocados em um array.middle.

Dois, use

Uso 1: um objeto pode usar o método de outro objeto durante a execução

function Doctor(){
    
    
    this.name = "Doctor";
    this.say = function(){
    
    
        console.log(this.name);
    }
}
function Stephen(){
    
    
    this.name = "Stephen Strange";
}
var doctor = new Doctor();
var stephen = new Stephen();
// 通过call将stephen对象传入doctor的say方法,此时say方法中的this被指向stephen对象
doctor.say.call(stephen);       //Stephen Strange

Uso 2: implementar herança

function Doctor(name){
    
    
    this.name = name;
    this.say = function(){
    
    
        console.log(this.name)
    }
}
function Stephen(name){
    
    
    //当前函数内的this指向函数Son的实例化对象
    //在执行Stephen时执行Doctor,同时将Doctor内的this改变成Stephen的this
    Doctor.call(this,name)
}

var doctor = new Doctor("Doctor")
doctor.say();       //Doctor
var stephen = new Stephen("Stephen Strange")
// 在Stephen中并没有say方法,但是因为在new Stephen时,执行了Doctor,
// 并将Doctor中的this指向Stephen的this,
// 那么在new Stephen后,得到的实例,也具有了Doctor内的属性和方法
stephen.say();      //Stephen Strange

Uso 3: herança múltipla

function People(){
    
    
    this.say = function(){
    
    
        console.log(`My name is ${
      
      this.name}. I will have ${
      
      this.attr} ${
      
      this.skill}.`)
    }
}
function Doctor(){
    
    
    this.skill = "cure";
}
function Magic(){
    
    
    this.attr = "Amazing";
}
function Stephen(name){
    
    
    this.name = name;
    // 执行其他函数的同时将原函数的this指向都改成Stephen的this,此时所有属性和方法可以互相访问
    People.call(this);
    Doctor.call(this);
    Magic.call(this);
}
var stephen = new Stephen("Stephen Strange");
stephen.say();      //My name is Stephen Strange. I will have Amazing cure.

Uso 4: Altere este ponto da função do sistema para realizar a transformação de pseudo array em array real

Sabemos que existem muitos tipos de (pseudo) arrays em js. Embora os pseudo arrays também armazenem dados de acordo com índices e tenham um atributo de comprimento, eles não possuem métodos de array, como push, pop, etc.
Se quisermos usar o método de array para operar o pseudo-array, precisamos primeiro converter o pseudo-array em um array real. Existem muitas maneiras de converter o pseudo-array em um real. Aqui falamos apenas sobre o uso o método de chamada para converter:

var ali = document.querySelectorAll("li");
// instanceof:查看一个实例是否指向某个构造函数的原型(查看一个实例是否属于某个类)
console.log(ali instanceof Array);      //false
// ali.push("hello");         //报错:ali.push is not a function

var arr = new Array(4,5,6);
// instanceof:查看一个实例是否指向某个构造函数的原型(查看一个实例是否属于某个类)
console.log(arr instanceof Array);      //true
arr.push("hello")
console.log(arr);         //[4,5,6,"hello"]

//此处开始转换
var aliZ = Array.prototype.slice.call(ali)
console.log(aliZ)
console.log(aliZ instanceof Array);     //true
// 此时aliZ就是一个真数组,可以使用数组的众多方法来操作
aliZ.push("world");
console.log(aliZ);       //[li,li,li,...,"world"]

Uso 5: Otimize o método do objeto Math

Os métodos min e max do objeto Math só podem aceitar vários dados, não um único array. Mas sabemos que os argumentos na função salvam todos os parâmetros reais passados. Aqui, o segundo parâmetro de apply é um array e substituirá as características dos argumentos originais da função. O array é passado por apply e entregue para mínimo ou máximo para processamento. Você pode obter rapidamente o valor máximo ou mínimo da matriz

var arr = [4,6,2,7,1];
console.log(Math.min(arr));             //NaN
console.log(Math.max(arr));             //NaN

console.log(Math.min.apply(null,arr))   //1
console.log(Math.max.apply(null,arr))   //7

Uso 6: Transforme o método de chamada do método do sistema

Sabemos que muitos métodos de instância em js são definidos no objeto protótipo do construtor, como Array.prototype.push/String.prototype.match/Function.prototype.bind, etc. método de chamada Para arr.push() / str.match() / fn.bind(), podemos usar a função call ou apply para alterar o método de chamada desses métodos de instância.
A chamada após a transformação é a seguinte: push(arr,"hello")

let arr = [3,4,5];
Array.prototype.push.call(arr,"hello")
console.log(arr);                       //[3,4,5,"hello"]

// 通过执行Function原型上的call方法的bind方法,改变call中原本应指向Function实例的this为Array.prototype.push,
// 并保存bind的返回值--改造之后的新call函数,放在newPush
const newPush = Function.prototype.call.bind(Array.prototype.push);
// 此时,call方法中的this指向为Array原型上的push方法,

// 执行newPush,相当于执行了Function.prototype.call.call(Array.prototype.push),
// call的第一个参数用来改变原函数this的指向,后call将前call中的this改成Array.prototype.push
// 此时后call执行,得到改变之后的前call
// 也就相当于得到了Array.prototype.push.call()
// 最终执行newPush相当于执行了Array.prototype.push.call()
newPush(arr,"world");
console.log(arr);                       //[3,4,5,"hello","world"]

// 此类改造还有:
const slice   = Function.prototype.call.bind(Array.prototype.slice);
console.log(slice(arr, 0, 2));          //[3,4]
const match = Function.prototype.call.bind(String.prototype.match);
console.log(match("a1ab12abc123", /\d+/g));     //["1", "12", "123"]

// 练习:使用相同方式尝试改造数组或字符的其他方法

3. Resumo

Na verdade, não importa onde esteja, basta ter em mente as funções dos métodos de chamada e aplicação: modifique o ponto this da função original e execute a nova função. Você pode controlar facilmente a chamada e aplicar métodos da função.

Perto do final, gostaria de mencionar outro método da função, bind. Na verdade, as funções de bing e call/apply são semelhantes, exceto que após bind modificar o ponto disso, a nova função retornada não será executada automaticamente . Se necessário, ela precisa ser executada manualmente; enquanto call e After apply alteram isso, a nova função retornada será executada automaticamente.


Escrito no final, resumido no artigo, caso esteja incompleto ou errado, deixe uma mensagem para apontar, obrigado pelo apoio... ^ _ ^

Acho que você gosta

Origin blog.csdn.net/weixin_41636483/article/details/115082774
Recomendado
Clasificación