[JS] Расскажите об этом указателе

внешний интерфейс JavaScript

5 минут, чтобы понять издание

Когда я впервые начал изучать JavaScript, меня часто смущали этот и связанные с ним методы в js, такие как методы связывания, применения и вызова. На самом деле нам нужно различать только по назначению метода, содержащего указатель this, мы можем понять объект, на который указывает указатель this:

1. Прямой вызов функции, этот указатель указывает на глобальную среду, то есть объект Window, например

2. Вызов функции объекта, этот указатель указывает на объект, вызывающий саму функцию, например:

var object={
    'name':"vicky",
    'sayName':function(){ console.log(this.name)}
};
object.sayName();   //this指针指向object对象,因此输出vicky

3. Вызывается конструктор, указатель this указывает на вновь созданный объект, например:

function object(name){
    this.name=name;
    console.log(this);      //由于this指向新创建的对象本身,输出:Object { name: "vikcy" }
    console.log(this.name);  //输出:"vicky"
}
var myObject=new Object('vicky');  //由于this指向新创建的对象本身

4. Косвенные вызовы функций, такие как вызов, методы применения и специальный метод связывания.

Подробный анализ этого указателя

1. Прямой вызов функции

Этот указатель указывает на глобальную среду, то есть на объект Window.

При вызове функции непосредственно в глобальной среде объект this будет указывать на объект Window, например:

var name='vicky'
function sayName(name){
    console.log(this.name);
}
sayName();   //this指向window对象,而因为在全局环境中定义了var name='vicky';所以this.name输出:vicky
window.sayName();  //sayName()效果等同于window.sayName()

2. Вызов функции объекта

указатель this указывает на сам объект, вызвавший функцию

var name='Bob';
function sayName(){
    console.log(this.name);
}
var object={'name':'vicky'};
object.sayName=sayName;          //sayName没有写成sayName(),表示不是执行函数,而是将sayName的指针赋值给object.sayName
object.sayName();               //由于对象函数调用方法,this指向对象本身,所以输出:'vicky'
sayName();                     //由于全局环境调用sayName()等同于window.sayName();输出:'Bob'

Приведенный выше пример был хорошей иллюстрацией разницы между прямым вызовом функции вызова в глобальной среде и вызовом объектной функции, когда указывает указатель this.

3. Вызов конструктора

этот указатель указывает на вновь созданный объект

function object(name){
    this.name=name;
    console.log(this);      //由于this指向新创建的对象本身,输出:Object { name: "vikcy" }
    console.log(this.name);  //输出:"vicky"
}
var myObject=new Object('vicky');  //由于this指向新创建的对象本身

Пример в начале был хорошей иллюстрацией того, что при вызове конструктора указатель this указывает на сам только что созданный объект.

Развернуть новые ключевые слова (с возможностью пропуска)

Но здесь я хочу расширить свои знания, и я хочу поговорить с вами о том, почему указатель this указывает на создаваемый объект при вызове конструктора, и что делает ключевое слово new?

Фактически, при вызове конструктора для создания объекта с помощью нового ключевого слова он прошел следующий процесс:

1. Создать новый объект и унаследовать прототип конструктора

2. Вызовите метод call(), примите параметры и измените точку this, чтобы она указывала на этот новый объект.

3. Выполнение конструктора.Если у конструктора есть возвращаемый объект, этот объект заменит новый объект, созданный на шаге 1. Если у конструктора нет возвращаемого значения, будет возвращен объект, созданный на шаге 1.

Если вы используете код для моделирования этого процесса, вы можете примерно сослаться на:

var newObject=function(func){
    var o={};  //创建一个新对象
    o.__proto__=func.prototype;  //继承构造函数prototype
    var k=func.call(o);         //调用call方法,修改this指向,指向这个新创建的对象
    if(typeof k=== 'object'){
        //如果构造函数有返回对象,则取代步骤1创建的对象,返回构造函数所返回的对象
        return k;
    }else{
        //如果构造函数没有返回对象,则直接返回步骤1创建的对象
        return o;
    }
}

В этом смоделированном коде есть небольшой недостаток, недостаток в том, что шаг принятия параметров не моделируется при вызове метода, но это не влияет на наше понимание нового ключевого слова.

Теперь давайте разберемся с работой нового ключевого слова выше на примере:

function Dog(name){
    this.name=name;
    console.log(this.name);    //输出'泰迪'
    console.log(this);        //输出:Object { name: "泰迪" }
}
Dog.prototype.sayName=function sayName(){
console.log("my name is "+this.name);
}
var animal=new Dog("泰迪");
animal.sayName();       //输出:'my name is 泰迪'

Приведенный выше код смог подтвердить следующие моменты:

1. Конструктор этот указатель указывает на только что созданный объект

2. Создать новый объект и унаследовать прототип конструктора

3. Вызовите метод call(), примите параметры и измените точку this, чтобы она указывала на этот новый объект.

для

Выполнение конструктора. Если у конструктора есть возвращаемый объект, этот объект заменит новый объект, созданный на шаге 1. Если у конструктора нет возвращаемого значения, верните объект, созданный на шаге 1.

На этом этапе давайте рассмотрим следующий пример:

function Cat(){
    console.log(this);   //输出:Object {  }
    console.log("cat"); 
}
function Dog(name){
    this.name=name;
    console.log(this.name);
    console.log(this);    //输出:Object { name: "泰迪" }
    return new Cat();    //关键代码,在构造函数返回了一个对象
}
var animal=new Dog("泰迪");   //输出:Object {  }

С помощью этого кода мы можем подтвердить:

Выполнение конструктора. Если у конструктора есть возвращаемый объект, этот объект заменит новый объект, созданный на шаге 1. Если у конструктора нет возвращаемого значения, верните объект, созданный на шаге 1.

На этом этапе мы возвращаем объект Cat в конце конструктора Dog, поэтому указатель животного указывает на экземпляр объекта new Cat(), возвращенный в конструкторе.

4. Косвенные вызовы функций, такие как вызов, методы применения и специальный метод связывания.

вызов (объект, на который указывает этот указатель, параметр 1, параметр 2,...)

Метод вызова может динамически устанавливать указатель this в теле функции, например:

function Cat(age,name){
    this.name='cat';
    console.log(this);
    console.log('cat: age:'+age+",name:"+name);
}
var cat=new Cat(4,'Bob');    //输出:Cat {name: "cat"}和cat: age:4,name:Bob
Cat.call(this,3,'Tom');     //由于调用了call方法,输出:this指向了Window和cat: age:3,name:Tom

Первый взгляд

var cat=new Cat(4,'Bob');В этой строке кода this указывает на только что созданный объект Cat, и выходные данные «cat: age:4,name:Bob» также передаются при инициализации объекта.

Cat.call(this,3,'Tom');Эта строка кода, где this указывает на объект Window, потому что: мы вызвали его в глобальной средеCat.call(this,3,'Tom');метод, здесь первый параметр функции вызова (объект, на который указывает указатель this) мы передаем в this, а this в глобальном окружении указывает на объект окна, а третий и четвертый параметры мы определяем соответственно age = > 3, имя => 'Том'

применить (объект, на который указывает этот указатель, массив параметров или объект аргументов)

Функция метода применения и метода вызова одинакова, единственное отличие состоит в том, что метод вызова передает параметры один за другим, а метод применения передает массив или объект аргументов. Объект arguments содержит все аргументы функции.

Пример:

function Cat(age,name){
    this.name='cat';
    console.log(this);
    console.log('cat: age:'+age+",name:"+name);
}
var cat=new Cat(4,'Bob');    //输出:Cat {name: "cat"}和cat: age:4,name:Bob
Cat.apply(this,[3,'Tom']);     //由于调用了apply方法,输出:this指向了Window和cat: age:3,name:Tom
function getCat(age,name){
    Cat.apply(this, arguments);    //arguments包含了函数的参数
}
getCat(5,"kitty");           //由于调用了apply方法,输出:this指向了Window和cat: age:5,name:kitty
bind (объект, на который указывает указатель this)

Метод bind создает экземпляр функции, чье значение this привязано к значению, переданному в функцию bind().

window.color = "red"; 
var o = { color: "blue" }; 
function sayColor(){ 
    console.log(this.color); 
    
} 
var objectSayColor = sayColor.bind(o); 
objectSayColor(); //由于调用了 sayColor.bind(o),bind函数返回的函数实例中的this直接绑定了o这个对象,
                    所以即使在全局环境调用函数objectSayColor,也会输出:"blue"
window.objectSayColor();   //输出:"blue"

Финальный повтор:

Итак, чтобы понять, на что это указывает, мы должны сначала выяснить, как вызывается функция, и, наконец, спросить себя, откуда берется объект, на который указывает this.

Я ячмень, если вам понравилась моя статья, пожалуйста, поставьте лайк.