Javascript中this对象详解

javascript this 基本 call apply

Redirected from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this

Introduction 导言

Javascript函数中的this关键字的行动比拟其他言语有许多差别。在Javascript的严厉形式下和非严厉形式下也略有差别。

在大多数情况下,函数的挪用体式格局决议了this的值。this不能在实行时期被赋值,在每次函数被挪用时this的值也会差别。ES5增加了bind要领,能够在不对函数举行挪用的情况下传入this值。

Global context 全局高低文

在全局高低文中(在任何函数体外部),this指代全局对象,不管是不是在严厉形式下。

console.log(this.doucment === 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

Function context 函数高低文

在函数内部, this的值取决于函数是怎样挪用的。

Simple call 直接挪用

function f1() {
        return this;
    }

f1() === window;  //global object

在这个例子中,this的值不是由函数挪用设定。由于代码不运行在严厉形式下,this的值始终是一个对象且默以为全局对象。

function f2() {
    "use strict";
    return this
    }

f2() === undefined;  //return undefined

在严厉形式下,this的值依据实行时的高低文,this所保留的值决议。若为定义,this还是undefined, 它能够被设置为任何的值,比方null,42或许是 ” I’am not this “。

在第二个例子中,this的值应该是undefined。由于f2被挪用时未基于任何对象(e.g.window.f2())。这个功用并未在一切第一次最先支撑严厉形式的浏览器中都取得普遍支撑,在不支撑的浏览器中,依然返回window,比方chrome。

As an object method 作为对象要领

当一个函数作为一个对象的要领被挪用,它的this会被设置为挪用该要领的对象。
鄙人面的例子中,当o.f()被挪用,function内部的this会绑定到这个object。

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

注重,怎样挪用或许在那边定义这个函数并不影响this的行动,在前一个例子中,我们在定义的object中为成员f增加了一个匿名函数,然则,我们能
更轻便的先定义这些函数然后再将其隶属到o.f上。如许做this的行动也是一致。

var o = {prop:37};
function independent(){
    return this.prop;
}

o.f = independent;

console.log(o.f());     //logs 37

这个例子只需o对象中的f才会令这个函数被挪用。

一样的,this绑定只会被最当前的援用所决议。在接下来的例子中,当我们挪用这个function,把它看成o.b对象的g要领挪用。在实行中,this会隶属到o.b上。这个对象自身作为o的成员没有效果,其返回效果就是当前援用。
如下例:

o.b = {g: independent, prop:37}
console.log(o.b.g());    //返回37
…在原型链中

只需要领是定义在对象的原型链中上面的挪用一样的依然准确,假如要领在一个对象的原型链中,this对象指向挪用这个要领的对象,就像这个要领存在于这个对象中一样。

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

在此例中,p对象并没有它自己的实例f属性,它继续于原型链。然则没有关系f能在o对象中找到;查找以一个p.f的援用最先,因而这个function中的this取对象p的援用值。也就是说,当f函数作为p的对象被挪用,它的this指向p。这是Javascript原型继续中非常风趣的特性。

…或许作为一个getter或许setter

当要领被getter或许setter挪用一样的观点依然建立,当对象的属性被set或许是gotten时,它的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); //返回-7.86  1.414

As a Constructor作为组织器

当函数作为组织器(运用new关键词),它的this绑定为新组织的对象。
注重:固然默许的组织器返回的this对象为当前挪用对象,它能被当前对象中return的新对象所庖代(假如对象的返回值不是对象,那末this仍指向当前对象)。

/*注重中示例*/
var o = {
    a : 12,
    f : function(){
        return this.a;
    }
    };
var p = {
    a : 21,
    f : function(){
    return o.f();
    }
    };

console.log(p.f()); //返回12

组织器示例

/*
 * 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);   //返回37

 function C2(){
    this.a = 38;
    return {a:38};
}
o = new C2();
console.log(o.a);    //返回38

在上一个例子中(c2),由于有一个对象在构建中返回,所以this对象绑定到了返回的对象上。

call和apply

在function内部运用this关键词时,它的值能够在运用call或apply(一切的function对象都继续自Function.prototype)挪用时绑定为该函数中传入的对象。

function add(c,d) {
    return this.a + this.b + c + d;
}
var o = {
    a : 2,
    b : 2
}
console.log(add.call(o,2,2)); //返回8

console.log(add.apply(o,[2,4])); //返回10

Bound functions 绑定函数

ECMAScript 5引见 Function.prototype.bind.挪用f.bind(someObject).建立一个新的function具有雷同的内容和作用域,比方f,然则this对象依然出现在本来的function中,在新的function中他依然永远的被绑定在第一个bind的参数(someObj)上,比方下面的g函数,不管这个function被挪用了多少次。

function f(){
    return this.a;
}

var g = f.bind({a : "penouc"});
console.log(g());

var  o = {a : 37,f : f, g : g};
console.log(o.f(),o.g());

As a DOM event handler 作为一个DOM事宜处置惩罚顺序

当一个function被用作为一个事宜处置惩罚顺序,它的this被设置为当前的元素(一些浏览器并不遵照这个划定规矩而是动态的增加要领比方运用addEventListener)。

//当元素被挪用,其被激活为蓝色
function bluify(e) {
    console.log(this === e.target);
    console.log(this === e.currentTarget);
    this.style.backgroundColor = "#A5D9F3";
}

//取得全部document的元素
var elements = document.getElementsByTagsName("*");

//当元素被点击时元素被挪用
for(var i = 0; i < elements.length; i++) {
    elements[i].addEventListener('click',bluify,false);
}

In an in-line event handler 在行内的事宜处置惩罚顺序

当代码被行内事宜处置惩罚顺序挪用,它的this就是当前元素:

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

以上正告为button。注重不管怎样只需在存在外层代码才设置为如许:

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

在这个例子中,内部的function的this并未设置因而返回为window/global对象。

    原文作者:penouc
    原文地址: https://segmentfault.com/a/1190000000501212
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞