Skip to content

Latest commit

 

History

History
261 lines (157 loc) · 5.89 KB

2017-06-28-JavaScript.this.md

File metadata and controls

261 lines (157 loc) · 5.89 KB

在javascript当中每一个function都是一个对象,所以在这个里var temp=this 指的是function当前的对象。this是Javascript语言的一个关键字。它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。

this出现的场景分为四类

1)、有对象就指向调用对象

2)、没调用对象就指向全局对象:window是js中的全局对象

3)、用new构造就指向新对象

4)、通过apply或者call或bind来改变this的指向

1、函数有所属对象时:指向所属对象

函数有所属对象时,通常通过 . 表达式调用,这时 this 自然指向所属对象。比如下面的例子:

var myObject = {value:100};
myObject.getValue = function() {

console.log(this.value);//输出100

console.log(this);//输出{value:100,getValue:function},其实就是myObject对象本身

return this.value;

}

console.log(myObject.getValue());//100

getValue()属于对象myObject(),并由myObject进行.调用,因此this指向对象myObject。

2、 函数没有所属对象:指向全局对象

var myObject = {value:100};
myObject.getValue = function() {

var foo = function() {

console.log(this.value);//undefined

console.log(this);//输出全局对象Window

};

foo();

return this.value;

};

console.log(myObject.getValue());//100

在上述代码块中,foo 函数虽然定义在 getValue 的函数体内,但实际上它既不属于 getValue 也不属于 myObject。foo 并没有被绑定在任何对象上,所以当调用时,它的 this 指针指向了全局对象 window.(PS:foo对象没有被上一级对象所调用,所以在这里this指向的就是全局对象window。)

另一种写法:

window.name = ‘xiaoming’;
function foo() {

console.log(this.name); //xiaoming

console.log(this);//全局对象window

}

foo();

3、构造器中的this:指向新对象

Js中我们通过new关键词来调用构造函数,此时this会绑定在新对象上。

var someClass = function() {
this.value = 100;

}

var myCreate = new someClass();

console.log(myCreate.value);

4、 apply 和 call 调用以及 bind 绑定:指向绑定的对象

Apply()方法接受两个参数,第一个是函数运行的作用域,另一个是参数数组(arguments)。

Call()方法第一个参数的意义与apply()方法相同,只是其他的参数需要一个个列举出来。

简单的来说,call的方式更接近我们平时调用函数,而apply需要传递Array形式的数组给它,它们可以相互转换的。

var myObject = {value:100};
var foo = function(){

console.log(this);

}

foo();//Window

foo.apply(myObject);//Object {value: 100}

foo.call(myObject);//Object {value: 100}

 

var newFoo = foo.bind(myObject);

newFoo();//Object {value: 100}

5、关于this的指向

this的指向在函数定义的时候是解决不了的,只有在函数执行的时候才能确定this到底指向谁,实际上this的最终指向是那个调用它的对象。

例一:

function a() {
var user = ‘admin’;

console.log(this);//Window

console.log(this.user);//undefined

}

a();

按照我们上面说的this最终指向的是调用它的对象,这里的函数a实际是被window对象多点出来的,下面的代码可以证明:

function a() {
var user = ‘admin’;

console.log(this);//Window

console.log(this.user);//undefined

}

window.a();

例二:

var a={
user:’admin’,

fn:function(){

console.log(this.user)//admin

console.log(this)//Object {user: “admin”, fn: function}  this指向的是a对象

}

}

a.fn();

这里的this指的是a,因为你调用这个fn是通过a.fn()执行的,那自然指向就是对象a,this的指向在行数创建的时候是决定不了的,在调用的时候才可以决定。

例三:推翻上面的理论

var a = {
user:’adimin’,

foo:function(){

console.log(this.user);//adimin

console.log(this);//Object {user: “adimin”, foo: function}

}

}

window.a.foo();//输出的是a对象里面的user

按道理来说this会指向调用它的对象,window是js中的全局对象,而我们创建的变量其实是给window添加属性,所以我们可以用window.a

例如:

var a = {
b:10,

foo:{

b:20,

show:function(){

console.log(this);//Object {b: 20, show: function}

//this指向的是 foo对象

}

}

}

a.foo.show();

a.foo.show();输出的是foo对象的内容,为什么会是foo?而不是a!下面分析一下this的几种情况:

1、如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版本中this指向的不是window,但是我们不讨论严格模式。

2、如果一个函数中有this,这个函数有被上一级对象调用,那么this指向的就是上一级的对象。

3、如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象调用,this指向的也只是它上一级的对象,上面的例子可以证明。

例四:继续探讨例三的情况

var a = {
b:10,

foo:{

show:function(){

console.log(this.b);//undefined

//this指向的是 foo对象

}

}

}

a.foo.show();

a.foo.show();输出的是undefined;从这里可以看出尽管对象foo中没有b这个属性,这个this指向的也是对象foo,因此this只会指向它的上一级对象,不管这个对象中有没有this要的东西。

例五:特殊情况

var a = {
b:10,

foo:{

b:20,

show:function(){

console.log(this.b);//undefined

console.log(this);//Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}

}

}

}

var j = a.foo.show;

j();

这里的this指向的是window,为什么会这样?因为:this永远指向的是最后调用它的对象。也就是看它执行的时候是谁调用的,上面的案例中show被foo引用,但是在将show赋值给变量j的时候并没有执行,所以最终指向的是window