依然是帮助新学JS的新人快速上手的简单教程.
和之前的教程一样是帮助大家阅读和模仿MV的源码而普及的基础知识
这是对修改甚至自己写脚本需要迈出的第一步.
1. this指针
this是一个指针,指向一个对象,在通常情况下它指的是代码的所有者.
更正应该是呼叫者
例子1:
JAVASCRIPT 代码
返回: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[0] = function(){console.log(this)}
- a.b();
- c[0]();
复制代码
返回: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在线咨询功能删除,谢谢。