Sobre isso em JavaScript
1. Processo de pré-compilação da função -> janela
function foo() {
console.log(this);
}
foo(); //全局变量
O this na chamada de função também aponta para uma variável global.
Nota: Não há variáveis globais no modo estrito de ECMAScript5, onde isso é indefinido.
2. Esta -> janela no escopo global
console.log(this); //全局变量
O escopo global usa isso para apontar para a variável global, que é a janela no ambiente do navegador.
Nota: Não há variáveis globais no modo estrito de ECMAScript5, onde isso é indefinido.
3. Chamada de método de objeto
var test = {
foo: function () {
console.log(this);
}
}
test.foo(); //test对象
Em chamadas de método de objeto, isso aponta para o chamador.
4. Chamada de construtor
Se uma chamada de função ou método é precedida pela palavra-chave new, ela constitui uma chamada de construtor. Use new para chamar uma função ou, quando ocorrer uma chamada de construtor, as seguintes operações serão executadas automaticamente.
- Crie um objeto vazio com var this = Object.create (foo.prototype) implicitamente na parte superior do corpo da função
- Execute this.xx = xx; adicione métodos de atributo a este
- Devolva isto implicitamente
function foo(x){
this.x = x;
console.log(this); // foo {x: 2}
}
var f = new foo(2);
console.log(f.x); // 2
Ao usar new para chamar foo (), um novo objeto será construído e vinculado a ele na chamada foo (). Ou seja, o this do construtor aponta para o objeto instanciado por ele.
5. call apply bind mudou isso
function foo(a, b) {
console.log(this);
}
var bar = {
};
foo.apply(bar, [1, 2]); //bar
foo.call(1, 2); //Number对象
Usando o método call ou apply de Function.prototype, isso dentro da função será definido como o primeiro parâmetro passado. Se indefinido e nulo após chamar e aplicar, isso aponta para a janela
6. Eventos de vinculação de elemento, isto na função executada após o evento ser disparado aponta para o elemento atual
<input type="button" value="点我">
<script>
document.querySelector("input").onclick = function(){
console.log(this); //指向当前按钮
};
</script>
Mude para
No ECMAScript, cada função contém dois métodos herdados: apply () e call (). O objetivo desses dois métodos é chamar a função em um escopo específico. A função principal é igual a bind. Altere o ponto disso no corpo da função ou alterar o contexto quando a função é chamada.
1. ligue e inscreva-se
apply () e call (), esses dois métodos são usados para chamar uma função em um escopo específico. A função principal é igual a bind, que é usado para alterar a direção deste no corpo da função ou para alterar o contexto quando a função é chamada.
Podemos usar esse recurso para implementar o código a seguir, emprestando outras funções para realizar nossas próprias funções:
function Person(name, age, sex) {
this. name = name;
this.age = age;
this.sex = sex;
}
function Student ( name, age, sex, tel, grade) {
// Person.call(this,name, age ,sex) ;
Person.apply(this,[name, age ,sex]) ;
this.tel = tel;
this.grade = grade;
}
var student = new Student( 'sunny', 123, 'male', 139, 2017)
console.log(student.name)//sunny
Podemos ver que não há atributo de nome no construtor Student original, e nosso call e apply são usados para alterar isso dinamicamente.
Aqui está outro exemplo de uso comum: o array não tem um método max, você pode usar o método max no objeto Math
const arr =[1,2,3,4,5]
const max = Math.max.apply(null,arr)
console.log(max)//5
chamar
O método call () usa um valor especificado e um ou mais parâmetros para chamar uma função.
fun.call (thisArg, arg1, arg, ...)
- thisArg é o valor especificado quando a função fun está em execução (no modo não estrito, quando especificado como nulo ou indefinido, ele apontará automaticamente para o objeto global)
- arg1.arg2 ... é a lista de parâmetros especificada
Aplique
fun.apply (thisArg, [argsArray])
- thisArg é este valor especificado quando a função fun está em execução (no modo não estrito, ele apontará automaticamente para o objeto global quando for especificado como nulo ou indefinido)
- argsArray é uma matriz ou um objeto semelhante a uma matriz, os elementos da matriz serão passados para a função divertida como parâmetros separados se
- Quando argsArray é nulo ou indefinido, significa que nenhum parâmetro precisa ser passado.
2. amarrar
fun.bind (thisArg, arg1, arg2,…).
- thisArg Quando a função vinculada é chamada, este parâmetro será usado como o ponto this da função original quando ela estiver em execução. Ao usar o novo operador para chamar a função de ligação, este parâmetro é inválido.
- arg1, arg2,… Quando a função vinculada é chamada, esses parâmetros são colocados antes dos parâmetros reais e passados para o método vinculado. // Se você vincular um novo this a uma determinada função e passar algumas variáveis primeiro, poderá passar no momento da vinculação. Depois disso, os parâmetros passados para chamar a nova função serão listados posteriormente.
const obj= {
}
function test(..args) {
console.log(args);
const newFn = test.bind(obj, 1,2);
newFn(3,4);
// [1,2,3,4]
3. Chamar resumo de ligação de aplicação
Vamos apenas olhar para a relação entre os três
//先来一个对象big吧
var big = {
name:'BaBa',
saying:function (age){
console.log(this.name,'age:',age);
}
};
//再来一个small对象
var small= {
name:'ErZi'
};
//如果想调用big的saying方法来说出‘Erzi’:
//使用bind方法
big.saying.bind(small)(20);//打印结果为ErZi age: 20
//使用call方法
big.saying.call(small,20);//打印结果为ErZi age: 20
//使用apply方法
big.saying.apply(small,[20]);//打印结果为ErZi age: 20
Resuma os três
1. Cenários de uso
- Quando uma função precisa mudar este ponto e há menos parâmetros, a chamada pode ser usada
- Se houver muitos parâmetros, você pode organizá-los em uma matriz e usar a aplicação
- Se você deseja gerar uma nova função para vincular um objeto por um longo tempo, você pode usar bind
2. Os mesmos pontos
são usados para alterar este ponto
3. Diferenças
- O mecanismo de uso de chamar e aplicar é quase o mesmo, a única diferença é que os parâmetros são diferentes. A função de chamada é passada em um parâmetro e o parâmetro de aplicação
é uma matriz. - O método de passagem de parâmetros de vinculação é igual ao de chamada, mas a direção da função de chamada é alterada e uma nova função é retornada.
Quando essa função é chamada posteriormente, isso aponta para o primeiro parâmetro de vinculação de vinculação
Expansão: Encapsule o método de ligação sozinho
//bind方法
//1、bind方法放在函数的原型中
// -->fn.__proto__===fn的构造函数.prototype
// -->所有的函数对象的构造函数是Function
// -->Function 创建了Function
// -->Function 创建了Object
// -->Function 创建了fn
Function.prototype._bind=function(target){
//这里的this其实fn
//target表示新函数的内部的this的值
//利用闭包创建一个内部函数,返回那个所谓的新函数
return ()=>{
//执行fn里面的逻辑
this.call(target); //this.apply(target)
}
// //等价于:
// var _that=this;
// return function(){
// _that.call(target);
// }
}
function fn(){
console.log(this);
}
var _f1=fn.bind({
age:18})