js的this指向

先补充基础知识 秘密花园  和  廖雪峰js

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() {
    varthat = this;
    // 使用 that 保存外部函数的 this
    //(防止被内部函数的 this 屏蔽)
 
    returnfunction() {
      returnthat.name;
      // 由于访问的是内部 AO 中没有的变量 that,
      // 所以在 SC 中外部的 AO 上搜索,
      // 得到外部函数的 this。
    };
  }
};
 
alert(object.getNameFunc()());// My Object


结论:在对象的方法的内部函数(可以认为是二级函数)不会自动指向当前的对象,即就是在对象的内部函数里面调用的函数,并不会自动继承指向对象的this指针,而是指向window或者undefined    请看js秘密花园中的 this



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章