JavaScript函数中的this指向并不是在函数定义的时候确定的,而是在调用的时候确定的。换句话说,函数的调用方式决定了this指向。

一、 全局上下文

在函数外部,无论是否在严格模式下,this都会指向全局对象window。

console.log(this.document === document); // true
// 在浏览器中,全局对象为window对象
console.log(this === window); // true
this.a = 20;
console.log(window.a); 

二、 函数上下文

在函数内部,this的值取决于函数是如何调用的。谁调用函数,this就指向谁。

1、 直接调用(默认绑定):未定义this值。

A、 在非严格模式下,this指向全局对象window或global。

function test(){
return this;
}
test() === window; // true

function test(){
this.x=1;
alert(this.x);
}
test();

var x=1;
function test(){
alert(this.x);
}
test();

var x=1;
function test(){
this.x=0;
}
test();
alert(x);

B、在严格模式下,this指向undefined。

function test(){
 "use strict"; // 这里是严格模式
  return this;
}
test() === undefined; // true

2、 对象方法中的this(隐式绑定):this指向对象。

当以对象里的方法的方式调用函数时,此时this指向调用该函数的对象。

var o = {
  age: 20,
  func: function() {
    return this.age;
  }
};
console.log(o.func()); // 20,this指向o

A、原型链中的this

如果该方法存在于一个对象的原型链上,那么this指向调用这个方法的对象。

var o = {
  func: function(){
    return this.a + this.b;
  }
};
var p = Object.create(o);
p.a = 1;
p.b = 4;
//对象p没有自己的func属性,它的func属性继承自它的原型。
console.log(p.func()); // 5,this指向p

B、getter和setter中的this

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); // -0.78 1.4142

3、构造函数中的this(new绑定):this指向新对象。

所谓构造函数,就是通过这个函数生成一个新对象。

function test(){
  this.x = 1;
}
var o = new test();
alert(o.x); 

function test(){
this.x = 1;
return {x : 2};
}
var o = new test();
alert(o.x); 

4、call和apply(显式绑定):this指向对象。

apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。apply()的参数为空时,默认调用全局对象。

var x = 0;
function test(){
  alert(this.x);
}
var o = {};
o.x = 1;
o.m = test;
o.m.apply(); //0,this指向全局
o.m.apply(o); //1,this指向o

function add(c, d){
  return this.a + this.b + c + d;
}
var o = {a:1, b:3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

使用call和apply函数的时候要注意,如果传递的this不是一个对象,JavaScript将会尝试使用内部ToObject操作将其转换为对象。7通过new Number(7)转化为对象,'foo'通过new String('foo') 转化为对象。

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

5、bind方法:this指向bind的第一个参数。

function test(){
  return this.a;
}
var nt = test.bind({a:"textstring"});
console.log(nt()); // textstring
var o = {a:20, f: test, g:nt};
console.log(o.f(), o.g()); // 20, textstring

6、dom事件处理函数中的this:this指向触发事件的元素。

// 被调用时,将关联的元素变成蓝色
function bluify(e){
  console.log(this === e.currentTarget); // 总是 true
  // 当 currentTarget 和 target 是同一个对象是为 true
  console.log(this === e.target);
  this.style.backgroundColor = '#A5D9F3';
}
// 获取文档中的所有元素的列表
var elements = document.getElementsByTagName('*');
// 将bluify作为元素的点击监听函数,当元素被点击时,就会变成蓝色
for(var i=0 ; i<elements.length ; i++){
  elements[i].addEventListener('click', bluify, false);
}

7、内联事件处理函数中的this:this指向DOM元素。

<button onclick="alert(this.tagName.toLowerCase());">
this指向button
</button>
<button onclick="alert((function(){return this})());">
没有设置内部函数的this,this指向window,即非严格模式下调用的函数未设置this时指向的默认对象。
</button>

细解javascript中的this关键字的更多相关文章

  1. 细解JavaScript ES7 ES8 ES9 新特性

    题记:本文提供了一个在线PPT版本,方便您浏览 细解JAVASCRIPT ES7 ES8 ES9 新特性 在线PPT ver 本文的大部分内容译自作者Axel Rauschmayer博士的网站,想了解 ...

  2. 详解javascript中的this对象

    详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...

  3. 如何理解JavaScript中的this关键字

    前言 王福朋老师的 JavaScript原型和闭包系列 文章看了不下三遍了,最为一个初学者,每次看的时候都会有一种 "大彻大悟" 的感觉,而看完之后却总是一脸懵逼.原型与闭包 可以 ...

  4. (转载)详解Javascript中prototype属性(推荐)

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...

  5. 【转】详解JavaScript中的this

    ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...

  6. 转载 深入理解JavaScript中的this关键字

    转载原地址: http://www.cnblogs.com/rainman/archive/2009/05/03/1448392.html 深入理解JavaScript中的this关键字   1. 一 ...

  7. JavaScript中的this关键字的用法和注意点

    JavaScript中的this关键字的用法和注意点 一.this关键字的用法 this一般用于指向对象(绑定对象); 01.在普通函数调用中,其内部的this指向全局对象(window); func ...

  8. 详解 javascript中offsetleft属性的用法(转)

    详解 javascript中offsetleft属性的用法 转载  2015-11-11   投稿:mrr    我要评论 本章节通过代码实例介绍一下offsetleft属性的用法,需要的朋友可以做一 ...

  9. javascript 中的 this 关键字详解

    1.javascript 中 什么是 this? this 指的是当前行为执行的主体,或者是当前方法执行的主体 context:是当前行为或者方法执行的环境 实例: xx 去北京饭店吃东西:上下文是“ ...

随机推荐

  1. android fragment解析

    1.fragment加载到Activity (1).添加fragment到Activity的布局文件 (2).动态在activity中添加fragment 例子: // 步骤1:获取FragmentM ...

  2. ubuntu下安装intel realsense驱动

    在安装之前一定要确保系统是ubuntu 14.04.3 64位! 由于一开始安装的是32位系统,导致在升级内核版本到4.4时各种问题,最终靠重装系统解决. 因为intel给出的测试代码均是在64位14 ...

  3. WPF复制异常问题(OpenClipboard 失败 (异常来自 HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN)))

    最近在维护WPF系统的时候发现的问题,刚刚开始自己的电脑都不能重现,后面写日志跟踪才发现问题的所在.问题主要是由于:1.   在程序访问剪切板的时候,有其他程序正在占用剪切板,导致自己的程序无法访问, ...

  4. 【转】inotify+rsync实现实时同步

    [转]inotify+rsync实现实时同步 1.1 什么是实时同步:如何实现实时同步 要利用监控服务(inotify),监控同步数据服务器目录中信息的变化 发现目录中数据产生变化,就利用rsync服 ...

  5. python2和3使用pip时的问题

    win10,电脑之前装有Anaconda,python2.因为需要用到python3,所以直接下载安装了python3.python3默认路径在c盘.我将其移到D盘并修改了两个环境变量.这时电脑的默认 ...

  6. HTML学习笔记06-连接

    HTML超链接 HTML使用标签<a>来设置文本超链接. 超链接可以是文字,也可以是图片,点击这些内容跳转到新的文档或当前文档的某个部分 代码类似这样: <a href=" ...

  7. ajax模拟获取json

    现在工作中我用到获取数据的方式,基本都是ajax.前台获取后端的数据后,需要进行处理,然后把他们放进页面中的相应标签里.下面举一个简单的例子,来模拟数据的获取和摆放. 这里用ng框架获取数据然后处理, ...

  8. discuz安装:mysqli_connect()不支持advice_mysqli_connect

    原文:http://blog.csdn.net/changzhi1990/article/details/40983247 php -m 输出: PHP Warning: PHP Startup: U ...

  9. Expm 7_2区间调度问题

    [问题描述] 给定n个活动,其中的每个活动ai包含一个起始时间si与结束时间fi.设计与实现算法从n个活动中找出一个最大的相互兼容的活动子集S. 要求:分别设计动态规划与贪心算法求解该问题.其中,对贪 ...

  10. VSCode配置python调试环境

    VSCode配置python调试环境 很久之前的一个东东,翻出来看看 VSCode配置python调试环境 * 1.下载python解释器 * 2.在VSCode市场中安装Python插件 * 4.在 ...