加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 沉滞的剑 于 2017-8-3 12:53 编辑
依然是帮助新学JS的新人快速上手的简单教程.
和之前的教程一样是帮助大家阅读和模仿MV的源码而普及的基础知识
这是对修改甚至自己写脚本需要迈出的第一步.
1. this指针
this是一个指针,指向一个对象,在通常情况下它指的是代码的所有者.更正应该是呼叫者
例子1:
返回:Window
结论:Window是所有全局代码的呼叫者.
例子2:
function a(){ function b(){ console.log(this) } console.log(this) b(); } a();
function a(){
function b(){
console.log(this)
}
console.log(this)
b();
}
a();
返回:Window, Window
例子3:
a = {}; a.b = function(){console.log(this)} c = []; c[0] = function(){console.log(this)} a.b(); c[0]();
a = {};
a.b = function(){console.log(this)}
c = [];
c[0] = function(){console.log(this)}
a.b();
c[0]();
返回:Object{....}和Array[...]
结论:通过上面的2个例子可以看出呼叫者是通过.或[]的语法关系体现的而和{}的层级无关.更正:呼叫者和被呼叫者的关系和被呼叫的函数所声明的位置无关,之和呼叫的主体有关。
例子4:
function a(){ console.log(this) } b = {}; b.c = a; b.c();
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:
function a(){ console.log(this.e); } b = {}; b.c = a; b.e = 'B'; d = {} d.e = 'D' b.c.call(d);
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:
function a(){ console.log(this.e); } b = {}; b.c = a; b.e = 'B'; d = {} d.e = 'D' b.c.apply(d);
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:
function a(){ console.log(this.e); } b = {}; b.c = a; b.e = 'B'; d = {} d.e = 'D' f = b.c.bind(d); f();
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:
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)();
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中还有一个蛋疼的东西叫原型和原型链, 我觉得我也有必要向新手普及一下
因为需要很多配图所以不知道猴年马月能更新...
(这个月不就是猴年马月么!!!)
|