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.
Я ячмень, если вам понравилась моя статья, пожалуйста, поставьте лайк.