1.在普通模式下和严格模式下,this指向不同,普通模式下this指向window全局变量,而严格模式指向undefined
2. 下面看这道题,会输出什么?
var length = 10;
function fn(){
console.log(this.length);
}
var obj = {
length:5,
method:function(fn){
fn();
arguments[0]();
}
}
obj.method(fn,1);
在严格模式下,输出10的那次的fn的this实际是undefined,在非严格模式下才成为了global,并且由于JavaScript允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没有问题,虽然函数内部并不需要这些参数
至于第二的arguments[0]()的输出,你就想一下,arguments[0]就是fn,相当于arguments['fn'](实际上只能用index来获得,这么写是方便你理解),这个this是arguments.
其实绑定this的,除了显式的bind,apply,call,就是通过object.foo或者object['foo']来绑定
3.绑定this的几个方法,绑定this的,除了显式的apply,bind,call(俗称ABC方法),就是通过object.foo或者object['foo']来绑定
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); // 数组将会被扩展,如下所示
foo.call(bar, 1, 2, 3); // 传递到foo的参数是:a = 1, b = 2, c = 3
bind的返回值是函数,并且
②后面的参数的使用也有区别
function f(a,b,c){ console.log(a,b,c); } var f_Extend = f.bind(null,"extend_A") f("A","B","C") //这里会输出--> A B C f_Extend("A","B","C") //这里会输出--> extend_A A B f_Extend("B","C") //这里会输出--> extend_A B C f.call(null,"extend_A") //这里会输出--> extend_A undefined undefined
这个区别不是很好理解
call 是 把第二个及以后的参数作为f方法的实参传进去,
而bind 虽说也是获取第二个及以后的参数用于之后方法的执行,但是f_Extend中传入的实参则是在bind中传入参数的基础上往后排的。
4.this 指向
* 全局范围内,当在全部范围内使用
this
,它将会指向全局对象。
* 作为一个对象的方法调用的时候,this 指向那个对象,比如 obj.fn()
* 作为一个普通函数(或者匿名函数)调用的时候,指向全局对象 window,比如 fn(),(这题属于这种情况,就算你把函数定义在里面也一样...)
* 构造函数中 this 指向实例化的对象
* 还有使用 call 和 apply 动态改变 this 的指向
举几个《JavaScript 高级程序设计》上第七章的栗子...
1. 不符合预期的闭包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
var
name = "The Window" ; var
object = { name: "My Object" , getNameFunc: function () { return function () { return
this .name; }; } }; alert(object.getNameFunc()()); // The Window (非严格模式下), // 此处有两个括号,因为 object.getNameFunc() 是一个匿名函数, // 后一个括号是匿名函数调用。 |
为什么匿名函数没有取得其包含作用域(或外部作用域)的 this 对象呢?
前面曾经提到过,每个函数在被调用时都会自动取得两个特殊变量:this 和 arguments。而内部函数在搜索这两个变量时,只会搜索到其 AO 为止,所以永远不能直接访问到外部函数中的 this 和 arguments。
不过若是我们将外部作用域中的 this 对象保存在一个闭包能够访问到的变量里,就可以让闭包访问到该对象了:
2. 符合预期的闭包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var
name = "The Window" ; var
object = { name: "My Object" , getNameFunc: function () { var that =
this ; // 使用 that 保存外部函数的 this //(防止被内部函数的 this 屏蔽) return function () { return that.name;
// 由于访问的是内部 AO 中没有的变量 that, // 所以在 SC 中外部的 AO 上搜索, // 得到外部函数的 this。 }; } }; alert(object.getNameFunc()()); // My Object |
结论:在对象的方法的内部函数(可以认为是二级函数)不会自动指向当前的对象,即就是在对象的内部函数里面调用的函数,并不会自动继承指向对象的this指针,而是指向window或者undefined
请看js秘密花园中的
this