如何保证 this, 是我们想要的 this 呢
有几个方法, 这里大致说下
1. 不把某个函数名, 直接赋值某个变量, 而是外面加一层函数, 然后再调用, 换句话说, 给你机会来让这个函数执行时指定调用者或者不设置调用者, 直接上代码
- [code]<section>
- <button id="btn" name="myBtn" style="width:100px;height:30px;"> 点击我 </button>
- </section>
- <script>
- var name="老姚";
- var btn = document.getElementById('btn');
- var f = function(){
- alert(this.name);
- };
- btn.onclick = f;
- </script>[/code]
上述代码, 点击按钮时弹出的是 btn 对象的 name:mybtn. 如果想要弹出 window 中的 name, 可以改成如下代码
- [code]<section>
- <button id="btn" name="myBtn" style="width:100px;height:30px;"> 点击我 </button>
- </section>
- <script>
- var name="老姚";
- var btn = document.getElementById('btn');
- var f = function(){
- alert(this.name);
- };
- btn.onclick = function(){
- f();
- };
- </script>[/code]
2. 设置变量缓存 this, 如
- [code]var name = "yyy";
- var Person = function(name){
- this.name = name;
- (function(){alert(this.name)})();
- }
- new Person("xxx");[/code]
上代码运行会弹出 window 的 name:yyy, 如果想弹出对象的 name:xxx, 可以改成
- [code]var name = "yyy";
- var Person = function(name){
- this.name = name;
- var self = this;
- (function(){alert(self.name)})();
- }
- new Person("xxx");[/code]
3. 应用 call,apply 方法来指定 this
- [code]var name = "yyy";
- var o = {name: "xxx"};
- var fun = function(x,y){
- alert(this.name)
- return x+y;
- }
- fun(3,4);
- // 等于于如下的调用
- fun.call(window,3,4);
- fun.call(this,3,4);
- fun.apply(window,[3,4]);
- fun.apply(this,[3,4]);
- [/code]
上述代码运行弹出 window 的 name:yyy, 如果要弹出 o 的 name, 可以改成
- [code]var name = "yyy";
- var o = {name: "xxx"};
- var fun = function(x,y){
- alert(this.name)
- return x+y;
- }
- fun.call(o,3,4);
- fun.apply(o,[3,4]);
- [/code]
4. 应用框架函数, 一般的框架都有给函数绑定上下文的函数 (基本也都是应用 apply 和 call), 比如 jquery 的 $.proxy(). 这里写个函数
- [code]function proxy(fn,context){
- return function(){
- return fn.apply(context,arguments);// 经网友提醒, fn 不仅要执行, 也要把原始的返回值, 带出去才行. 本文最开始少写了这个 return.
- }
- }[/code]
举例如下
- [code]var o = {name: "xxx"};
- var fun = function(x,y){
- alert(this.name)
- return x+y;
- }
- var fun2 = proxy(fun,o);
- fun2(3,4);[/code]
本文完, 如果你觉得我讲得明白的话给个反馈, 点个赞, 留个言啥的. 先谢过了.
补充: 2015 年 10 月 25 日
最近看了 js 语言精粹, 书中总结了函数的四种调用模式
1. 方法调用模式
2. 函数调用模式
3. 构造器调用模式
4.apply 调用模式
其中这个第二条, 说的就是不管全局直接调用还是局部作用域调用, this 总是指向全局的. 说是 js 中, 这块是语言设计的 bug,bug 也好, 非 bug 也好, 我们注意就好了.
来源: http://www.qdfuns.com/article/17398/acec15c23873633f33f1d6830451705b.html