J'ai lu le livre "JavaScript You Don't Know" plusieurs fois. Il semble qu'à chaque fois que je le lis, je fais de nouvelles découvertes. Une partie du contenu ne peut pas être comprise d'un coup, mais il me semble comprendre certains concepts. chaque fois que je le lis.
Relisez à nouveau le this
mot-clé. Le concept est très flexible et très difficile à comprendre, je ne vois donc aucun inconvénient à le lire souvent. J'espère que JavaScript sera populaire dans le monde, donc le coût de l'apprentissage sera faible !
Référez-vous au chapitre 1 et au chapitre 2 de la deuxième partie de ce livre.
Ce mot-clé est l'un des mécanismes les plus complexes de js. Il est automatiquement défini dans le périmètre de toutes les fonctions.
Il semble que j'aie aussi fait un long détour dans le processus d'apprentissage de ce mot-clé. Il faut me demander pourquoi j'ai fait un long détour. Le point clé est que je n'ai pas encore complètement appris et compris les concepts de base. Ce n'est pas différent des élèves du primaire qui apprennent de nouvelles connaissances. Si vous voulez maîtriser le mot-clé ceci, vous devez vous en tenir aux concepts clés et ne pas imaginer de quoi il s'agit.
Concept clé : lorsqu'une fonction en js est appelée, elle sera certainement liée à un objet. Lors de l'analyse du mot-clé this, vous devez savoir quel est l'objet lorsque la fonction est appelée. .
Rappelez-vous : il n'y a aucune relation entre l'appel et la définition d'une fonction en js. L'objet lié à la fonction ne peut pas être connu tant qu'il n'est pas appelé.
L'incertitude de ce mot-clé est une arme à double tranchant. L'une est l'incertitude de l'objet lorsque la fonction est appelée. L'utilisation des fonctions en js est très flexible. Chaque objet peut emprunter d'autres fonctions pour compléter. la fonction. Deuxièmement, cela a également causé quelques problèmes d’apprentissage. Ainsi, lors de l'apprentissage, vous devez d'abord comprendre les avantages de ce mot-clé, puis vous rendre aux endroits qui posent problème
Regardez d'abord le premier code
page 75
//注意只是定义了一个函数,并未调用,这时候函数是没有绑定任何对象function identify() {return this.name.toUpperCase(); }//同上面的函数,但是这个函数内部有点复杂,如果下面的代码看不懂//可以只看上面的函数function speak() {var greeting = "Hello, I'm " + identify.call( this );console.log( greeting ); }var me = { //定义了一个字面量对象 name: "Kyle" };var you = {//定义了一个字面量对象 name: "Reader" };//通过call方式把函数identify分别绑定到两个对象上//这时的this是指向me对象,和you对象 identify.call( me ); // KYLE identify.call( you ); // READER//通过call方式把函数call分别绑定到两个对象上//这时的this是指向me对象,和you对象 speak.call( me ); // Hello, I'm KYLE speak.call( you ); // Hello, I'm READER
Lors de la définition d'une fonction en JavaScript, la fonction n'appartient à aucun objet. C’est très critique, très critique, très critique. C’est le premier obstacle à la compréhension de ce mot-clé.
L'incertitude de ce mot-clé lors de la définition des fonctions js rend l'utilisation des fonctions js extrêmement flexible, et n'importe quel objet peut l'utiliser.
La liaison de ceci n'a rien à voir avec l'emplacement de la définition de la fonction, seulement 取决于函数调用的方式
.
Lorsqu'une fonction est appelée en JavaScript, un enregistrement d'activité (parfois également appelé contexte) sera créé. Cet enregistrement inclut l'endroit où la fonction a été appelée, la méthode d'appel de la fonction et les paramètres transmis. il s'agit d'un attribut dans l'enregistrement.
De cette façon, vous pouvez apprendre des mots-clés javascript首要问题是要解决怎么知道到函数的调用位置
.
Chaque fonction js doit trouver un objet lorsqu'elle est appelée, 绑定
Ne peut être utilisé que plus tard. C'est le concept le plus important qui doit être maîtrisé après avoir compris la différence entre la définition et l'appel des fonctions js. Personnellement, les règles de liaison ne sont pas difficiles, 难点还是在js的函数作用域的理解
Surtout 默认绑定
. la méthode est extrêmement déroutante.
Il s'agit d'un appel indépendant de la fonction. Autrement dit, lorsqu'une fonction est appelée directement, elle ne semble pas être liée à l'objet. Cependant, selon le précédent. introduction, dans js Les appels de fonction doivent être liés à un objet.
Regardez la page de codes suivante 83
function foo() { //这是函数的定义位置console.log( this.a ); } var a = 2;//这个变量定义的含义是什么呢?仅仅是赋值给a吗? foo(); // 2 //这是函数的调用位置。为什么会打印出2呢?
De nombreuses fonctions sont appelées de cette manière. Vous pouvez également les écrire en imitant un chat ou un tigre, mais c'est différent si vous comprenez le. signification spécifique.
La fonction foo est définie dans la portée globale (portée de la fenêtre). Par coïncidence, son appel est également dans la portée globale. Notez que ce n'est qu'une coïncidence. Alors pourquoi la valeur de la variable s'imprime-t-elle lorsque foo() est appelée ? Bien que le mot-clé var soit utilisé, nous pouvons savoir grâce à l'analyse de portée que la variable a est en fait une variable globale, pour être plus clair, a est en fait un attribut de la fenêtre d'objet globale et 2 est la valeur d'attribut de cet attribut. .
Lorsque foo() est appelé, il est dans un état nu. Il s'agit simplement de la fonction elle-même sans aucun modificateur. Pour le moment, elle n'a aucun wrapper de fonction et est dans la portée globale, donc ceci dans foo(. ) pointe vers Pour les objets globaux, lorsque vous souhaitez imprimer this.a, recherchez l'emplacement appelant de foo() et vous trouverez la portée globale. Lorsque vous recherchez l'attribut this.a de la portée globale, vous imprimerez. sur la valeur d'attribut 2.
Lorsque nous utilisons les fonctions setTimeout et setInterval, ces deux fonctions sont en fait nues et sont également liées à l'objet window.
Des modificateurs sont ajoutés à la fonction lorsqu'elle est appelée. Regardez le code suivant
page 85
function foo() { //定义在全局作用下的函数,仅仅是定义,不是调用位置console.log( this.a ); }var obj = { //定义一个对象 a: 2,foo: foo }; obj.foo(); // 2 给foo()函数找了一个对象,this就指向这个对象了
C'est la méthode la plus courante. Si vous n'écrivez pas l'obj précédent, sera-ce la liaison par défaut ci-dessus ?
隐式丢失
Vous voyez souvent la phrase au début de la fonction externe dans la fonction de rappel imbriquée du code js
var that=this; //这是什么含义
Peut-être que vous l'avez déjà utilisée, mais vous comprenez-le, ce sera plus facile d'utiliser le sens
看下面段代码.这段代码其实以前我也不太理解,问题还是没有彻底领悟js函数定义和调用之间是没有关系的这一点。
page 86
function foo() { //定义了一个函数console.log( this.a ); }var obj = { //定义了一个对象字面量 a: 2,foo: foo //函数作为对对象的属性 };var bar = obj.foo; //把obj对象的函数foo属性赋值给bar变量//这里就是理解这个问题的关键,如果你现在认为调用bar()的时候绑定的对象//是obj那就完全搞错了。这个时候仅仅是把函数foo赋值给了var变量,//并没有把对象也给bar变量,因为这里还不是foo()函数的调用位置,现在//foo函数还没有绑定对象,那么调用bar()的时候对象到底是谁?不知道。//调用的时候才知道。var a = "oops, global"; // 任然是全局对象的属性 bar(); // "oops, global" 这里执行的是默认绑定,this就是去全局对象啦
下面这段代码就是使用var that=this的场景
在使用回调函数的时候要留心。js中函数是一等对象,可以作为另一个函数的参数传入函数。 问题就出在这里了,函数一旦作为实参代替形参的时候,实际也执行了和上面代码一样的赋值过程,实际只是传递了函数本身,原先的对象就没有了。
page 86
function foo() { //定义一个函数console.log( this.a ); }function doFoo(fn) { //fn是形参// 如果函数作为实参传入相当于代码 var fn=obj.foo//和上面一段代码是完全一样的,只是函数本身,并没有绑定任何对象 fn(); // 在这里调用的时候,由于fn只代表foo()函数,被绑定到全局对象上了 }var obj = {a: 2,foo: foo };var a = "oops, global"; // `a` also property on global object doFoo( obj.foo ); // "oops, global"不要被obj.foo迷惑了//没有实际执行函数的调用,此时obj.foo仅仅代表没有绑定任何对象的函数//这个代码块看着眼熟么?这就是javascript中回调函数的样子,当//一个函数作为参数传递进另一个函数的时候,这个参数函数就找不到自己绑定的对象是谁了,//所以就默认绑定到全局对象上了。但是我们既然在一个函数里调用另一个函数,肯定是要用这个函数操作当前的对象,那么既然找不到了,我们就手动给他指定一个对象吧。这就是为什么要使用//var that=this的原因。我觉得理解这个概念,js的功力至少会增加5%
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!