在函数执行时,this 总是指向调用该函数的对象。要判断 this 的指向,其实就是判断 this 所在的函数属于谁。

在《javaScript语言精粹》这本书中,把 this 出现的场景分为四类,简单的说就是:

有对象就指向调用对象
没调用对象就指向全局对象
用new构造就指向新对象
通过 apply 或 call 或 bind 来改变 this 的所指。

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

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

1
2
3
4
5
6
7
8
9
10
11
12
var myObject = {value: 100};
myObject.getValue = function () {
 console.log(this.value); // 输出 100
 
 // 输出 { value: 100, getValue: [Function] },
 // 其实就是 myObject 对象本身
 console.log(this);
 
 return this.value;
};
 
console.log(myObject.getValue()); // => 100

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
var myObject = {value: 100};
myObject.getValue = function () {
 var foo = function () {
  console.log(this.value) // => undefined
  console.log(this);// 输出全局对象 global
 };
 
 foo();
 
 return this.value;
};
 
console.log(myObject.getValue()); // => 100

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

据说这是个设计错误。

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

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

1
2
3
4
5
6
7
var SomeClass = function(){
 this.value = 100;
}
 
var myCreate = new SomeClass();
 
console.log(myCreate.value); // 输出100

顺便说一句,在 js 中,构造函数、普通函数、对象方法、闭包,这四者没有明确界线。界线都在人的心中。

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
var myObject = {value: 100};
 
var foo = function(){
 console.log(this);
};
 
foo(); // 全局变量 global
foo.apply(myObject); // { value: 100 }
foo.call(myObject); // { value: 100 }
 
var newFoo = foo.bind(myObject);
newFoo(); // { value: 100 }

以所述就是本文的全部内容了,希望大家能够喜欢。

【转】javascript中this的四种用法的更多相关文章

  1. javascript中this的四种用法

    javascript中this的四种用法 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2015-05-11我要评论 在javascript当中每一个function都是一个对象,所 ...

  2. C#中 this关键字 四种用法

    /// <summary> /// 主程序入口 /// </summary> /// <param name="args"></param ...

  3. c++中for的四种用法

    #include <algorithm> #include <vector> #include <iostream> using namespace std; in ...

  4. Javascript中函数的四种调用方式

    一.Javascript中函数的几个基本知识点: 1.函数的名字只是一个指向函数的指针,所以即使在不同的执行环境,即不同对象调用这个函数,这个函数指向的仍然是同一个函数. 2.函数中有两个特殊的内部属 ...

  5. C#中this的 四种 用法

    C#中的this用法,相信大家应该有用过,但你用过几种?以下是个人总结的this几种用法,欢迎大家拍砖,废话少说,直接列出用法及相关代码. this用法1:限定被相似的名称隐藏的成员 /// < ...

  6. javascript中函数的四种调用模式详解

    介绍函数四种调用模式前,我们先来了解一下函数和方法的概念,其实函数和方法本质是一样,就是称呼不一样而已.函数:如果一个函数与任何对象关系,就称该函数为函数.方法:如果一个函数作为一个对象属性存在,我们 ...

  7. Javascript 中 call 的两种用法

    用法一(常见用法): 表现形式为:一个对象.方法.call(另一个对象),意义是用另一个对象代替当前对象,执行当前对象的方法.先看示例: function Class1(){ this.name = ...

  8. js中this 的四种用法

    this 在函数执行时,this 总是指向调用该函数的对象.要判断 this 的指向,其实就是判断 this 所在的函数属于谁. 在<javaScript语言精粹>这本书中,把 this  ...

  9. VBA中Option的四种用法

    1.Option Explicit.当使用Option Explicit时,必须在模块中的所有过程声明每一个变量,否则会出现语法错误并不能被编译.这样做的好处是,它能消除程序中因为错拼变量名而导致程序 ...

随机推荐

  1. enter键实现自动登录

    将登录窗口的属性acceptbutton更改为登录按钮!

  2. 垂直的SeekBar:VerticalSeekBar

    public class VerticalSeekBar extends AbsSeekBar { private Drawable mThumb; public interface OnSeekBa ...

  3. su和su - 的区别

    Linux中切换用户的命令是su或su -.前天我在使用useradd这个命令时,才体会到这两者的本质区别.如图: 我首先是用su命令切换到root身份的,但是运行useradd时,出现错误:bash ...

  4. FireBug使用总结

    FireBug是一个用于网站前端的开发工具,它是Firefox浏览器的一个拓展插件,它可以调试JavaScript.查看DOM.分析CSS.监控网络流量以及进行Ajax交互等.提供了几乎前端开发需要的 ...

  5. HDU3987 Harry Potter and the Forbidden Forest(边数最少的最小割)

    方法1:两遍最大流.一遍最大流后,把满流边容量+1,非满流边改为INF:再求最小割即为答案. 我大概想了下证明:能构成最小割的边在第一次跑最大流时都满流,然后按那样改变边容量再求一次最小割,就相当于再 ...

  6. Gap

    Gap Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  7. BZOJ1409 : Password

    $f[n]\bmod q=p^{Fib[n]}\bmod q=p^{Fib[n]\bmod\varphi(q)}\bmod q$ 首先线性筛预处理出所有素数,然后对于每次询问,求出$\varphi(q ...

  8. BZOJ2862 : 分糖果

    二分答案$x$表示最大的一段的和. 设$f[i]$表示前$i$个最多分几段,满足最大的一段不超过$x$,若$f[n]\geq k$,则可行, 则$f[i]=\max(f[j])+1,sum[i]-su ...

  9. Zepto源码注释

    /* Zepto v1.0-1-ga3cab6c - polyfill zepto detect event ajax form fx - zeptojs.com/license */ ;(funct ...

  10. 【NOIP2003】传染病控制(-贪心/dfs)

    我自己yy了个贪心算法,在某oj 0msAC~.然后去wikioi提交,呵呵,原来是之前oj的数据太弱给我水过了,我晕. 我之前的想法是在这棵树上维护sum,然后按时间来割边,每一时刻割已经感染的人所 ...