じ☆ve冰风 发表于 2024-2-13 14:30:02

简明易懂的this指针, call, apply 和 bind教程

依然是帮助新学JS的新人快速上手的简单教程.
和之前的教程一样是帮助大家阅读和模仿MV的源码而普及的基础知识
这是对修改甚至自己写脚本需要迈出的第一步.

1. this指针
this是一个指针,指向一个对象,在通常情况下它指的是代码的所有者.更正应该是呼叫者
例子1:
JAVASCRIPT 代码
console.log(this)

返回:Window
结论:Window是所有全局代码的呼叫者.
例子2:
JAVASCRIPT 代码
function a(){
function b(){
console.log(this)
}
console.log(this)
b();
}
a();

返回:Window, Window
例子3:
JAVASCRIPT 代码
a = {};
a.b = function(){console.log(this)}
c = [];
c = function(){console.log(this)}
a.b();
c();

返回:Object{....}和Array[...]
结论:通过上面的2个例子可以看出呼叫者是通过.或[]的语法关系体现的而和{}的层级无关.更正:呼叫者和被呼叫者的关系和被呼叫的函数所声明的位置无关,之和呼叫的主体有关。
例子4:
JAVASCRIPT 代码
function a(){
console.log(this)
}
b = {};
b.c = a;
b.c();

返回:Object{...}
结论: this和函数声明所在的{}层级无关, 只和对象的层级有关和上面的结论一致.

总结: this指针的指向判断要根据上下文, 也就是代码的所有者, 调用者. 注意看.和[]来判断从属关系.
2.call, apply 和 bind
以上讨论的仅是一般情况.
作为动态语言, js支持更改this指针的上下文, 也就是说改变this的指向.
最常用的就是call函数
call函数的作用是替换this指针, 立刻呼叫这个函数
call函数的格式如下
Function.prototype.call(this指针指向的对象,函数的参数1, 函数的参数2......)
例子1:
JAVASCRIPT 代码
function a(){
console.log(this.e);
}
b = {};
b.c = a;
b.e = 'B';
d = {}
d.e = 'D'
b.c.call(d);

输出: 'D'
结论: call函数改变了this指针的指向
apply函数和call函数是等价的, 只是参数上有少许变化:
Function.prototype.apply(this指针指向的对象,[函数的参数1, 函数的参数2......])
例子2:
JAVASCRIPT 代码
function a(){
console.log(this.e);
}
b = {};
b.c = a;
b.e = 'B';
d = {}
d.e = 'D'
b.c.apply(d);

输出:'D'
结论: apply除了把参数用一个数组包起来以外...嗯...基本和call没区别.
bind也是用来改变this上下文的, 和call格式上很像
Function.prototype.bind(this指针指向的对象,[函数的参数1, 函数的参数2......])
但是有一点很重要, bind并不是执行函数, 而是返回函数对象.
也就是说bind本身不会执行函数, 它返回了一个修改过this指针的新函数.
例子3:
JAVASCRIPT 代码
function a(){
console.log(this.e);
}
b = {};
b.c = a;
b.e = 'B';
d = {}
d.e = 'D'
f = b.c.bind(d);
f();

输出:'D'
结论: bind和call或apply不同, 并不会直接执行函数而是返回了一个修改过this指针指向的新函数.
接下来展示几个带参数的用法.
例子4:
JAVASCRIPT 代码
a = {};
b = {};
c = function(str, num){
console.log(this.e);
console.log(str + ':' + (++num));
}
a.e = 'A'
b.e = 'B'
a.d = c;
a.d.call(b,'HeartCase',3)
a.d.apply(b,['HeartCase',3])
a.d.bind(b,'HeartCase',3)();

输出:B, HeartCase:4,B, HeartCase:4,B, HeartCase:4
结论: 以上三种写法是等价的
关于call, apply 和 bind使用的奇技淫巧是很多的
对于想要了解js原理的人来说, 对这三个函数的掌握是非常重要的,它们也有很多高级进阶技巧
但是对我们这些基础的使用者,至少对RM来说保持良好的可读性才是第一位的
弄懂了这些, 帮助你阅读源码是十分有利的.

总结:
this指针指向的是代码的所有者
利用call, bind 和 apply可以修改this指针的指向

其他: js中还有一个蛋疼的东西叫原型和原型链, 我觉得我也有必要向新手普及一下
因为需要很多配图所以不知道猴年马月能更新...
(这个月不就是猴年马月么!!!)


             本帖来自P1论坛作者沉滞的剑,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=394122若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页: [1]
查看完整版本: 简明易懂的this指针, call, apply 和 bind教程