Javascript this用法

语法

this


全局对象

在全局执行上下文(函数之外),this引用的是全局对象.

1
2
3
4
5
6
7
console.log( this .document === document); // true
 
// In web browsers, the window object is also the global object:
console.log( this  === window); // true
 
this .a = 37;
console.log(window.a); // 37


函数

在函数里面,this这个值,得看怎么来调用这个函数

简单的调用

1
2
3
4
5
function  f1(){
   return  this ;
}
 
f1() === window; // global object


在这个例子中,this不是没有被赋予任何值.没有申明为严格模式下,this必须要有一个值去赋予.默认情况下就是指向的是全局对象.

1
2
3
4
5
6
function  f2(){
   "use strict" ; // see strict mode
   return  this ;
}
 
f2() === undefined;

严格模式下, this没有被申明,则为undefined.他也可以是任何值,比如null或者42或者其他.

作为一个对象的方法

当一个函数作为一个对象的方法去调用,this指向的是对象本身.

下面的例子中,当 o.f()被调用,函数里面的this指向的是 o对象.

1
2
3
4
5
6
7
8
var  o = {
   prop: 37,
   f: function () {
     return  this .prop;
   }
};
 
console.log(o.f()); // logs 37

假如 o 对象只申明了一个属性,其f方法在开始声明时还没有被定义,然后通过o.f直接被赋值为其他方法,其最后的效果也是一样的,只是定义的前后问题,this依然指向的是o这个对象:

1
2
3
4
5
6
7
8
9
var  o = {prop: 37};
 
function  independent() {
   return  this .prop;
}
 
o.f = independent;
 
console.log(o.f()); // logs 37

这个例子说明的是f函数的调用,是作为o的成员方法来执行.

我们继续来看,如果我们给o设定另外一个成员属性b赋予为一个对象,看下面这个例子,这时候,this该指向的是谁呢? 前面已经说过,this指向的是对象本身,所以o.b作为一个对象,同样这个对象的this指向的是他自己o.b.

1
2
o.b = {g: independent, prop: 42};
console.log(o.b.g()); // logs 42

对象原型链中的this

同样的概念也使用对象原型链中

1
2
3
4
5
6
var  o = {f: function (){ return  this .a + this .b; }};
var  p = Object.create(o);
p.a = 1;
p.b = 4;
 
console.log(p.f()); // 5

在这个例子中,对象p没有自己的属性.它继承了o的属性.所以这时候通过p来调用f方法,this指向的是p,这是对象原型模式.这里就是javascript中的原型继承模式.


this与getter和setter

再次,用相同的概念也适用于getter和setter.函数使用getter或者setter来绑定到对象的属性.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function  modulus(){
   return  Math.sqrt( this .re * this .re + this .im * this .im);
}
 
var  o = {
   re: 1,
   im: -1,
   get phase(){
     return  Math.atan2( this .im, this .re);
   }
};
 
Object.defineProperty(o, 'modulus' , {
     get: modulus, enumerable: true , configurable: true });
 
console.log(o.phase, o.modulus); // logs -0.78 1.4142


作为一个构造函数

.当一个函数作为一个构造函数使用(同构new来构造).this这时候指向的是函数构造出来的对象.

提示: 虽然默认构造函数返回对象引用,它也可以返回其他对象 .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
  * Constructors work like this:
  *
  * function MyConstructor(){
  *   // Actual function body code goes here. 
  *   // Create properties on |this| as
  *   // desired by assigning to them.  E.g.,
  *   this.fum = "nom";
  *   // et cetera...
  *
  *   // If the function has a return statement that
  *   // returns an object, that object will be the
  *   // result of the |new| expression.  Otherwise,
  *   // the result of the expression is the object
  *   // currently bound to |this|
  *   // (i.e., the common case most usually seen).
  * }
  */
 
function  C(){
   this .a = 37;
}
 
var  o = new  C();
console.log(o.a); // logs 37
 
 
function  C2(){
   this .a = 37;
   return  {a:38};
}
 
o = new  C2();
console.log(o.a); // logs 38

在最后的例子中(C2),因为一个对象在构造函数期间返回,这个新对象就会被丢弃.("this.a=37"; 其实没什么作用的代码.但是他也不是完全是死码,因为他被执行了.但是没有影响到外面的代码执行.)

 

call 和 apply

一个函数在内部使用this,通过使用call或者apply方法将它的值绑定到一个特殊的对象.所有方法继承Function.prototype.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function  add(c, d){
   return  this .a + this .b + c + d;
}
 
var  o = {a:1, b:3};
 
// The first parameter is the object to use as
// 'this', subsequent parameters are passed as
// arguments in the function call
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
 
// The first parameter is the object to use as
// 'this', the second is an array whose
// members are used as the arguments in the function call
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

我们来看下下面的这个列子.bar.call(7)这一行代码,将第一个参数为一个数值,则这时候的bar方法里面的this是指向Number.到这里,你可以试试执行另外的一行代码 new Number(10).toString(),看看效果.

1
2
3
4
5
function  bar() {
   console.log(Object.prototype.toString.call( this ));
}
 
bar.call(7); // [object Number]


bind方法

ECMAScript 5 介绍了 Function.prototype.bindbind是创建了一个新函数而不是修改一个函数.新函数的行为和原来函数的行为一样,但他的接收者是我们给定的对象,而原有函数的接收者保持不变.

1
2
3
4
5
6
7
8
9
function  f(){
   return  this .a;
}
 
var  g = f.bind({a: "azerty" });
console.log(g()); // azerty
 
var  o = {a:37, f:f, g:g};
console.log(o.f(), o.g()); // 37, azerty


作为DOM事件处理

当一个函数用在事件处理上.他的this将是指向这个元素的本身事件(使用addEventListener添加监听器事件中,有些浏览器不遵守公约,有自己的一套做法.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// When called as a listener, turns the related element blue
function  bluify(e){
   // Always true
   console.log( this  === e.currentTarget);
   // true when currentTarget and target are the same object
   console.log( this  === e.target);
   this .style.backgroundColor = '#A5D9F3' ;
}
 
// Get a list of every element in the document
var  elements = document.getElementsByTagName( '*' );
 
// Add bluify as a click listener so when the
// element is clicked on, it turns blue
for ( var  i=0 ; i<elements.length ; i++){
   elements[i].addEventListener( 'click' , bluify, false );
}


内联事件处理

当代码在元素上进行调用处理,this指向的是这个DOM元素.

1
2
3
<button onclick= "alert(this.tagName.toLowerCase());" >
   Show this
</button>

上面显示的是这个按钮. 记住只有这种方式,返回的是这个元素.

1
2
3
<button onclick= "alert((function(){return this}()));" >
   Show inner this
</button>

在这个例子中,内部函数this没有被设置,因此它返回的全局对象window.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值