Maison > Article > interface Web > Où JavaScript pointe-t-il ?
Cela pointe vers : 1. Fonction ordinaire ou en tant qu'attribut d'objet, pointant vers l'objet window ; 2. Dans la liaison d'événement, pointant vers l'élément de l'événement lié ; 3. Dans le constructeur, pointant vers le instance de la classe ; 4. Flèche Dans la fonction, il pointe vers son contexte parent le plus proche ; 5. Dans call/apply/bind, il pointe vers le premier paramètre transmis.
L'environnement d'exploitation de ce tutoriel : système windows7, javascript version 1.8.5, ordinateur Dell G3
JavaScript
Le this
le pointeur est divisé en Les situations suivantes :
call/apply/bind
SpécifiezPrésentons-les une par une
this
Dépend Y a-t-il un « point » devant l'exécution de la méthode ? S'il y a un « point », celui qui se trouve devant le « point » est this
S'il n'y a pas de point, this
pointe vers window
<.>
const fn = function () { console.log(this); }; const obj = { name: 'OBJ', fn }; fn(); obj.fn(); const fn1 = obj.fn; fn1();réponse :
1. window 2. {name: 'OBJ', fn: function() {console.log(this)}} // obj 3. windowpeut voir que lorsqu'une fonction est appelée en tant qu'attribut d'un objet, son
pointe vers l'objet qui appelle la fonction, sinon son this
pointe vers la liaison d'événement this
window
dans la fonction de liaison d'événement est l'élément permettant de lier l'événement : this
// 假设页面中有id为button的button元素 // var x = 100; window.x = 100; const fn = function () { console.log(this.x); }; const obj = { x: 200, fn }; const $button = document.getElementById('button'); $button.x = 300; obj.fn(); const fn1 = obj.fn; fn1(); $button.addEventListener('click', fn); $button.addEventListener('mouseenter', obj.fn); $button.addEventListener('mouseleave', function () {obj.fn();});réponse :
1. 200 2. 100 3. 点击button时:300 4. 鼠标移入button时:300 5. 鼠标移出时:200Mais il est à noter qu'ici lorsque l'utilisateur clique, le navigateur nous aide à pointer le
de l'événement de clic vers l'élément this
lié à l'événement. Si l'événement correspondant est déclenché via le code, nous pouvons spécifier son constructeur DOM
call/apply/bind
$button.click.call() // this为window,打印结果为100
this
(new Fn
via ) est exécuté. Le new Fn
dans la fonction est une instance de la classe actuelle. C'est ce que le mot-clé this
nous aide à faire : new
var x = 100; const Fn = function () { this.x = 200; console.log(this.x); }; const fn = new Fn();answer:
1. 200
, et le this
utilisé est la this
this
const fn = function () { console.log(this); setTimeout(() => { console.log(this); }, 1000); setTimeout(function () { console.log(this); }); }; const obj = { x: 100, fn }; obj.fn();réponse :
1. {x:100, fn: function() {...}} // obj 2. window 3. {x:100, fn: function() {...}} // obj
call/apply/bind
pour pointer vers this
Le premier paramètre transmis est le call/apply/bind
de la fonction : this
var x = 100; const obj = { x: 200, y: 200 }; const fn = function () { console.log(this.x); }; fn(); fn.call(obj); fn.apply(obj); const fixedThisFn = fn.bind(obj); fixedThisFn();réponse :
1. 100 2. 200 3. 200 4. 200
call
, et les paramètres suivants sont les paramètres de this
exécutionfn
apply
, et les paramètres suivants sont un tableau composé de paramètres lors de l'exécution de this
. Chaque élément du tableau correspondra à chaque paramètre de fn
fn
. bind
La valeur de retour est une fonction this
, fn
fixedThisFn
sera appelé en interne et précisera que son fixedThisFn
pointe vers fn
this
dans le. fonction, simulons et implémentons ces trois fonctions séparément call/apply/bind
this
call/apply/bind
D'après l'introduction précédente, nous savons : quand une fonction est appelée comme. un attribut d'objet, const obj = { x: 100, fn () {console.log(this);} }; obj.fn(); // {x: 100, fn: function() {...}} => obj
this
En utilisant la fonctionnalité de , nous pouvons utiliser la fonction exécutée comme attribut du premier paramètre de JavaScript
, puis appelez la fonction correspondant à l'attribut via call/apply
, le context
de la fonction pointe alors vers context
this
context
Function.prototype.myOwnCall = function (context, ...args) { const uniqueKey = new Date().getTime(); // this为调用call方法的函数 context[uniqueKey] = this; // 作为对象的方法被对象调用,this指向该对象context const result = context[uniqueKey](...args); delete context[uniqueKey]; return result; };À ce stade, certains amis ont peut-être découvert que si
call
entrant Et si ce n'était pas un objet ? call/apply
Regardons d'abord la context
description du premier paramètre de la méthode
mdn
Syntaxe : call
function.call(thisArg, arg1, arg2, ...)
Facultatif . La valeur
utilisée lorsque la fonctionthisArg
est exécutée. Notez que
peut ne pas être la valeur réelle vue par cette méthode : si cette fonction est en mode non strict,function
sera automatiquement remplacé lors de la spécification dethis
outhis
pour pointer vers l'objet global, et la valeur d'origine sera Wrappingnull
undefined
Ensuite, nous traitons le premier paramètre de la méthode
comme suit :
function translateToObject (context) { // 可以通过 == 进行判断 context == null // null == undefined => 2个等号是成立的 // null,undefined => window if (typeof context === 'undefined' || context === null) { context = window; } else if (typeof context === 'number') { // 原始值转换为包装对象 context = new Number(context); } else if (typeof context === 'string') { context = new String(context); } else if (typeof context === 'boolean') { context = new Boolean(context); } return context; }
Appelez la fonction dans la méthode myOwnCall
:
Function.prototype.myOwnCall = function (context, ...args) { context = translateToObject(context); const uniqueKey = new Date().getTime(); // this为调用call方法的函数 context[uniqueKey] = this; // 作为对象的方法被对象调用,this指向该对象context const result = context[uniqueKey](...args); delete context[uniqueKey]; return result; };
est fondamentalement la même que celle de myOwnCall
, sauf que le deuxième paramètre est un tableau :
Function.prototype.myOwnBind = function (context, paramsArray) { context = translateToObject(context); const uniqueKey = new Date().getTime(); // this为调用call方法的函数 context[uniqueKey] = this; // 作为对象的方法被对象调用,this指向该对象context const result = context[uniqueKey](...paramsArray); delete context[uniqueKey]; return result; };
相比于call/apply
,bind
函数并没有立即执行函数,而是预先传入函数执行时的this
和参数,并且返回一个函数,在返回的函数中执行调用bind
函数并将预先传入的this
和参数传入
bind
的源码模拟:
Function.prototype.myOwnBind = function (context, ...outerArgs) { const fn = this; return function (...innerArgs) { return fn.call(context, ...outerArgs, ...innerArgs); }; };
精简版如下:
Function.prototype.myOwnBind = (context, ...outerArgs) => (...innerArgs) => this.call(context, ...outerArgs, ...innerArgs);
这里并没有实现通过new
操作符来执行fn.bind(context)
的操作,如果想知道其详细的实现过程,可以看我的这篇文章: JS进阶-手写bind
在深入理解call/apply/bind
的实现原理后,我们尝试完成下面的测试:
function fn1 () {console.log(1);} function fn2 () {console.log(2);} fn1.call(fn2); fn1.call.call(fn2); Function.prototype.call(fn1); Function.prototype.call.call(fn1);
answer:
1. 1 2. 2 3. 什么都不输出 4. 1
这里我们根据call
的源码来进行推导一下Function.prototype.call.call(fn1)
,其它的执行过程类似:
// 1. 首先会将Function.prototype.call作为一个函数来执行它原型上的call方法 // 所以call方法内部: // this => Function.prototype.call // context => fn1 // 通过对象的属性来执行方法改变this指向 // fn1[uniqueKey] = this(Function.prototype.call) // fn1[uniqueKey]() // 执行 Function.prototype.call方法,但是this是context // 2. 在this为fn1的情况下执行Function.prototype.call方法 // 所以call方法内部: // this => fn1 // context => window // 通过对象的属性来改变this指向 // window[uniqueKey] = fn1 // window[uniqueKey]() // 执行fn1(),但是this是window
更多编程相关知识,请访问:编程入门!!
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!