语法

this

全局对象

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

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这个值,得看怎么来调用这个函数

简单的调用

function f1(){
return this;
} f1() === window; // global object

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

function f2(){
"use strict"; // see strict mode
return this;
} f2() === undefined;

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

作为一个对象的方法

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

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

var o = {
prop: 37,
f: function() {
return this.prop;
}
}; console.log(o.f()); // logs 37

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

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.

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

对象原型链中的this

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

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来绑定到对象的属性.

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这时候指向的是函数构造出来的对象.

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

/*
* 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.

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(),看看效果.

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

bind方法

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

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添加监听器事件中,有些浏览器不遵守公约,有自己的一套做法.)

// 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元素.

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

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

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

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

本文属于吴统威的博客,微信公众号:bianchengderen 的原创文章,转载时请注明出处及相应链接:http://www.wutongwei.com/front/infor_showone.tweb?id=156 ,欢迎大家传播与分享.

this详解:JAVASCRIPT中的this到底是谁?的更多相关文章

  1. 详解javascript中的this对象

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

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

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

  3. 【转】详解JavaScript中的this

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

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

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

  5. 详解JavaScript中的原型

    前言 原型.原型链应该是被大多数前端er说烂的词,但是应该还有很多人不能完整的解释这两个内容,当然也包括我自己. 最早一篇原型链文章写于2019年07月,那个时候也是费了老大劲才理解到了七八成,到现在 ...

  6. 详解JavaScript中的Event Loop(事件循环)机制

    前言 我们都知道,javascript从诞生之日起就是一门单线程的非阻塞的脚本语言.这是由其最初的用途来决定的:与浏览器交互. 单线程意味着,javascript代码在执行的任何时候,都只有一个主线程 ...

  7. 【转】详解JavaScript中的异常处理方法

    有三种类型的编程错误:(1)语法错误和(2)运行时错误(3)逻辑错误:语法错误: 语法错误,也被称为解析错误,在编译时进行传统的编程语言,并出现在JavaScript解释时. 例如,下面一行将导致一个 ...

  8. 详解JavaScript中的arc的方法

    今天说说JavaScript在网页中画圆的函数arc! 一.arc所需要的参数设置 1 arc(x, y, radius, startAngle, endAngle, counterclockwise ...

  9. 详解JavaScript中的Url编码/解码,表单提交中网址编码

    本文主要针对URI编解码的相关问题做了介绍,对Url编码中哪些字符需要编码.为什么需要编码做了详细的说明,并对比分析了Javascript 中和 编解码相关的几对函数escape / unescape ...

随机推荐

  1. Eclipse下安装及配置maven项目管理工具

    ①eclipse下maven插件安装. 本地maven安装.环境变量配置完成后,打开eclipse,点击eclipse菜单栏Help->Eclipse Marketplace搜索关键字maven ...

  2. HDU 2089 不要62(挖个坑=-=)

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  3. Poj 2478-Farey Sequence 欧拉函数,素数,线性筛

    Farey Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14291   Accepted: 5647 D ...

  4. centos6.5建立cloudera-cdh4.6本地源

    1.准备:      centos6.5系统,root用户 2.安装所需包:      sudo yum install yum-utils createrepo 3.下载cdh4.6的repo:   ...

  5. Java GC 专家系列3:GC调优实践

    本篇是”GC专家系列“的第三篇.在第一篇理解Java垃圾回收中我们学习了几种不同的GC算法的处理过程,GC的工作方式,新生代与老年代的区别.所以,你应该已经了解了JDK 7中的5种GC类型,以及每种G ...

  6. 自己生成非官方iPhone toolchain的头文件

    如果你已经搭建好非官方iPhone toolchain开发包,如果缺少某些头文件,可以用以下方法自己生成. 首先下载class-dump: http://www.codethecode.com/pro ...

  7. iOS-实现映客首页TabBar和滑动隐藏NavBar和TabBar

    之前在做直播的时候,参照了映客App,发现其首页的效果还挺不错,在网上找了一下相关仿映客App代码和博客,大部分都是说如何播放直播流和推流,对于UI这块甚少,所以我自己花了点时间研究了一下映客的首页U ...

  8. c++ 流基本概念

    前言 在程序经常实现数据的输入和输出,c++通过一种称为流(stream)的机制提供了更为精良的输入和输出方法.流是一种灵活且面向对象的I/o方法. 根据操作对象不同分为文件流.字符串流.控制台流. ...

  9. BufferedInputStream详解

    BufferedInputStream是一个带有缓冲区域的InputStream,它的继承体系如下:  InputStream  |__FilterInputStream          |__Bu ...

  10. Myeclipse2013 SVN安装方法

    1. 打开Help下的Install from Site 2. 弹出窗口,如下图: 3. 点击Add标签,如图: 在对话框Name输入Svn, URL中输入:http://subclipse.tigr ...