Cet article vous apporte une compréhension approfondie de cela en Javascript ECMA (avec des exemples). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Il s'agit en fait d'une liaison qui se produit lorsque la fonction est appelée, et ce vers quoi elle pointe dépend entièrement de l'endroit où la fonction est appelée (c'est-à-dire de la manière dont la fonction est appelée).
Quatre règles : (JS vous ne connaissez pas)
1. Liaison par défaut
function foo() { console.log( this.a ); } var a = 2; foo(); // 2
si ou. not En mode strict, dans le contexte d'exécution global (en dehors de tout corps de fonction) ceci fait référence à l'objet global. (MDN)
En mode strict, ceci conservera sa valeur lorsqu'il entrera dans le contexte d'exécution. Si celle-ci n'est pas définie par le contexte d'exécution, elle restera indéfinie. (MDN)
function foo() { "use strict"; console.log( this.a ); } var a = 2; foo(); // TypeError: this is undefined
Lorsque des fonctions sont appelées en tant que méthodes dans des objets, c'est l'objet qui appelle la fonction, et la liaison n'est affectée que par le référence du membre le plus proche. (MDN)
//隐式绑定 function foo() { console.log( this.a ); } var obj2 = { a: 42, foo: foo }; var obj1 = { a: 2, obj2: obj2 }; obj1.obj2.foo(); // 42
//隐式丢失 function foo() { console.log( this.a ); } function doFoo(fn) { // fn 其实引用的是 foo fn(); // <-- 调用位置! } var obj = { a: 2, foo: foo }; var a = "oops, global"; // a 是全局对象的属性 doFoo( obj.foo ); // "oops, global"
Si vous souhaitez transmettre la valeur de this d'un contexte à un autre, vous devez utiliser la méthode call ou apply. (MDN)
Appeler f.bind(someObject) créera une fonction avec le même corps de fonction et la même portée que f, mais dans cette nouvelle fonction, elle sera définitivement liée au premier paramètre de bind, quelle que soit la manière dont cette fonction. est appelé.
var obj = { count: 0, cool: function coolFn() { if (this.count < 1) { setTimeout( function timer(){ this.count++; // this 是安全的 // 因为 bind(..) console.log( "more awesome" ); }.bind( this ), 100 ); // look, bind()! } } }; obj.cool(); // 更酷了。
Crée une fonction wrapper qui transmet tous les paramètres et renvoie toutes les valeurs reçues.
La liaison matérielle réduira considérablement la flexibilité de la fonction. Après avoir utilisé la liaison matérielle, vous ne pouvez pas utiliser la liaison implicite ou la liaison explicite pour modifier cela.
// 简单的辅助绑定函数 function bind(fn, obj) { return function() { return fn.apply( obj, arguments ); }; }
Spécifiez un objet global et une valeur autre que non définie pour la liaison par défaut, vous pourrez alors obtenir le même effet qu'une liaison dure tout en conservant la liaison implicite Ou lier explicitement le possibilité de modifier cela.
Function.prototype.softBind = function(obj) { var fn = this; var curried = [].slice.call( arguments, 1 );// 捕获所有 curried 参数 var bound = function() { return fn.apply( (!this || this === (window || global))?obj : this curried.concat.apply( curried, arguments ) ); }; bound.prototype = Object.create( fn.prototype ); return bound; };
Lorsqu'une fonction est utilisée comme constructeur (à l'aide du nouveau mot-clé), elle est liée au nouvel objet en cours de construction. (MDN)
Utilisez new pour appeler une fonction, ou lorsqu'un appel de constructeur se produit, les opérations suivantes seront automatiquement effectuées (JS vous ne connaissez pas)
Créer (ou construct ) un objet complètement nouveau.
Ce nouvel objet sera connecté par [[ prototype ]].
Ce nouvel objet sera lié au this de l'appel de fonction.
Si la fonction ne renvoie aucun autre objet, alors l'appel de fonction dans la nouvelle expression renverra automatiquement ce nouvel objet.
function foo(a) { this.a = a; } var bar = new foo(2); console.log( bar.a ); // 2
Priorité à quatre règles
nouvelle liaison> liaison explicite> liaison par défaut>
var bar = new foo()
De plus :
En cas de liaison null ou undefined , les règles de liaison par défaut sont effectivement appliquées.
var bar = foo.call(obj2)
var bar = obj1.foo()
var bar = foo()
Les fonctions de référence indirecte appliqueront les règles de liaison par défaut
function foo() { console.log( this.a ); } var a = 2; var o = { a: 3, foo: foo }; var p = { a: 4 }; o.foo(); // 3 (p.foo = o.foo)(); // 2
1. Fonction flèche
La fonction flèche n'utilise pas les quatre règles standard de celle-ci, mais la détermine en fonction de la portée externe (fonction ou globale).
Dans les fonctions fléchées, ceci est cohérent avec le this du contexte lexical englobant. (MDN)Les fonctions fléchées héritent de la liaison this de l'appel de fonction externe (peu importe à quoi cela est lié). C'est en fait le même mécanisme que self = this.
Les liaisons des fonctions fléchées ne peuvent pas être modifiées.
setTimeout(function() { console.log(this) //浏览器中:window //nodejs中:Timeout实例 }, 0)
https://www.zhihu.com/questio. ..
func(p1, p2) est équivalent àfunc.call(undefined, p1, p2)
obj.child.method(p1, p2) est équivalent à
Si le contexte que vous transmettez est nul ou indéfini, alors l'objet window est le contexte par défaut (le contexte par défaut en mode strict est indéfini)
var number = 50; var obj = { number: 60, getNum: function () { var number = 70; return this.number; } }; alert(obj.getNum()); alert(obj.getNum.call()); alert(obj.getNum.call({number:20}));
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!