JS中的 this 变化多端,似乎难以捉摸,但实际上对 this 的解读,还是有一定规律的。

分析this,该如何下手呢?下面有一个函数

function show(){
  alert(this);
}

那 this 是什么呢?当然没有答案,因为要得到 this,首先要看调用处。调用决定this ,如下

oBtn.onclick = show;  // 此时 this 就是 oBtn
show();               // this 是 window 或 undefined,具体要看方法的所有者和运行模式
new show()            // this 是 new 出来的对象

下面分析几种单一情况下的 this:

1、事件中,this指向触发事件的对象
1.1、作为事件处理程序的值

oBtn.onclick = function(){
  alert(this);      // oBtn
}

1.2、行间事件

<input type="button" value="按钮" id="btn" onclick="show()" />
function show(){
  alert(this);  // this指该按钮
}

1.3、同样是行间事件

<input type="button" value="按钮" id="btn" onclick="alert(this)" />
<!-- this也是指该按钮 -->

2、this 指向其所属的对象。包括普通函数,可以看成是 window 的对象。
2.1

var arr=[1,2,3];
arr.show=function ()
{
    alert(this);   // this指向arr数组
};
arr.show();

2.2

function show(){
  alert(this);  // window
}
show();

等价于(此处只关心 this)

window.show=function ()
{
    alert(this);    //window
};
window.show();

3、函数嵌套

function show(){
    function show1(){
        alert(this);
    }
    show1();
}
show();

结果:
3.1、正常下 this 指向 window;
3.2、严格模式下,this 为 undefined (当然浏览器得支持严格模式);
可以这么理解:this指向其所属的对象,此时show1谁都不属于,所以是undefined

4、定时器中,this 指向 window,可以这么理解:隔一段时间后,由 window 执行一个函数,所以 this 指向 window;

setTimeout(function(){
    alert(this);    // window
}, 1000);

5、apply 和 call,正如我们知道的,call 和 apply 可以改变 this 的值

function show(){
    alert(this);   // this 指向数组
}
show.call([1,2,3]);

6、new 对象
*构造函数:构造函数式相对的, new Person()时,Person 就叫构造函数,直接调用"Person()"时,Person就是一个普通的函数;

function Person (){
    alert(this);     // new 出来的 Person 对象
}
var person = new Person();

new的作用:
1.将 this 指向一个新建的空对象
2.return this

所以上面的代码实际是这样的:

function Person (){
    // var obj = new Object();
    // this = obj;
    alert(this);     // new 出来的 Person 对象
    // return this;
}
var person = new Person();

单种情况的处理基本就如上了,如果复合情况怎么办?如下:

function show(){
    alert(this);
}
var arr1=[1,2,3];
arr1.show=show;
setTimeout(new arr1.show(), 1000);

此时就需要对上述几种情况按照优先级排一个顺序了

this 优先级从高到低为:

优先级 情景 this 的值 备注
1 new new出来的空 object  
  apply / call 传入的参数 并列第一,apply / call不能和 new 同时出现
new arr1.show.apply(“1”); // 报错
2 定时器 window  
3 事件 发生事件的元素  
4 方法 所有者  
5 其他(嵌套等) window || undefined 看是否为严格模式

注:不管如何修改this,this只会影响一层,比如下面这个

function show(){
    alert(this);        // this 为数组 [1,2,3]
    function show1(){
        alert(this);    // window || undefined
    }
    show1();
}
show.apply([1,2,3]);

下面的 this 就没什么疑问了吧(某些代码纯粹是为了判断 this 而写,实际中并不会遇到–面试除外)

function show()
{
    alert(this);
}
var arr1 = [1,2,3];
arr1.show = show;

show();         //window
arr1.show();    //arr1

new show();         //object
new arr1.show();    //object

//document.onclick = show;      //点击时 document
document.onclick = arr1.show;   //点击时 document

new document.onclick();         //object

setTimeout(show, 100);          //window
setTimeout(arr1.show, 200);     //window

setTimeout(document.onclick, 100);  //window
setTimeout(new document.onclick(), 200);    //object

window.onload = function ()
{
    arr1.show();            //arr1
};

new (function (){
    alert(this);            //object
    arr1.show();            //arr1
})();

JS中的 this的更多相关文章

  1. 5.0 JS中引用类型介绍

    其实,在前面的"js的六大数据类型"文章中稍微说了一下引用类型.前面我们说到js中有六大数据类型(五种基本数据类型 + 一种引用类型).下面的章节中,我们将详细讲解引用类型. 1. ...

  2. 【repost】JS中的异常处理方法分享

    我们在编写js过程中,难免会遇到一些代码错误问题,需要找出来,有些时候怕因为js问题导致用户体验差,这里给出一些解决方法 js容错语句,就是js出错也不提示错误(防止浏览器右下角有个黄色的三角符号,要 ...

  3. JS中给正则表达式加变量

    前不久同事询问我js里面怎么给正则中添加变量的问题,遂写篇博客记录下.   一.字面量 其实当我们定义一个字符串,一个数组,一个对象等等的时候,我们习惯用字面量来定义,例如: var s = &quo ...

  4. js中几种实用的跨域方法原理详解(转)

    今天研究js跨域问题的时候发现一篇好博,非常详细地讲解了js几种跨域方法的原理,特分享一下. 原博地址:http://www.cnblogs.com/2050/p/3191744.html 下面正文开 ...

  5. 关于js中的this

    关于js中的this this是javascript中一个很特别的关键字,也是一种很复杂的机制,学习this的第一步就是要明白this既不指向函数自身也不指向函数的词法作用域,this实际上是函数被调 ...

  6. 表值函数与JS中split()的联系

    在公司用云平台做开发就是麻烦 ,做了很多功能或者有些收获,都没办法写博客,结果回家了自己要把大脑里面记住的写出来. split()这个函数我们并不陌生,但是当前台有许多字段然后随意勾选后的这些参数传递 ...

  7. JS中 call() 与apply 方法

    1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...

  8. 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查

    Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...

  9. 分析js中的constructor 和prototype

    在javascript的使用过程中,constructor 和prototype这两个概念是相当重要的,深入的理解这两个概念对理解js的一些核心概念非常的重要. 我们在定义函数的时候,函数定义的时候函 ...

  10. 如何在Node.js中合并两个复杂对象

    通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...

随机推荐

  1. Linux I2C设备驱动编写(二)

    在(一)中简述了Linux I2C子系统的三个主要成员i2c_adapter.i2c_driver.i2c_client.三者的关系也在上一节进行了描述.应该已经算是对Linux I2C子系统有了初步 ...

  2. 机器学习-review-1 线性回归

    发现隔一段时间,忘记了好多知识点,这里认为重要的知识点记录下来,作为笔记,方便以后回顾. From “李航- 统计学习方法” 统计学习方法的三要素: 模型,策略, 算法 对于线性回归 -------- ...

  3. Linux开机自动挂载Windows分区

    使用Linux的朋友肯定都不会对本文所谈的内容陌生,在Linux系统里,通常不会开机自动挂载Windows文件系统下的分区.Ubuntu系统下要点击Windows分区才会挂载,Fedora下则甚至要输 ...

  4. weekend110(Hadoop)的 第三天笔记

    (2015年1月17日) 课程目录 01-hdfs源码跟踪之打开输入流 02-hdfs源码跟踪之打开输入流总结 03-mapreduce介绍及wordcount 04-wordcount的编写和提交集 ...

  5. 关于ASSERT(断言)的作用

    程序一般分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本发行给用户使用.断言assert 是仅在Debug 版本起作用的宏,它用于检查“不应该”发生的情况 ...

  6. spf13配置问题

    git clone https://github.com/spf13/spf13-vim.git tab是黑的色 加入这样一行就可以了set nolist if下的黑边在~/.vimrc里面吧inde ...

  7. 如何判断Linux是否适合你

    如果你厌烦了windows,或者想延长旧pc的寿命,也或者想给小孩使用一款os,linux都能满足你. 开源操作系统linux的关键优势: - 免费的. - 大部分linux软件也是免费的. - li ...

  8. ThreadLocal 和Synchronized

    并发都用到, 两个都是解决了线程并发问题,区别呢? Synchronized  同步机制, 共有变量被多个线程使用,会出现线程不安全,所以,加锁,锁机制很多种,例如Synchronized, lock ...

  9. [Webpack 2] Validate your Webpack config with webpack-validator

    It’s quite common to make a mistake while developing your webpack configuration. A simple typo can c ...

  10. OpenStack_Swift源代码分析——创建Ring及加入�设备源代码算法具体分析

    1 创建Ring 代码具体分析 在OpenStack_Swift--Ring组织架构中我们具体分析了Ring的具体工作过程,以下就Ring中添加�设备,删除设备,已经又一次平衡的实现过程作具体的介绍. ...