资讯专栏INFORMATION COLUMN

Javascript中this对象详解

glumes / 3167人阅读

摘要:返回作为构造器当函数作为构造器使用关键词,它的绑定为新构造的对象。注意当然默认的构造器返回的对象为当前调用对象,它能被当前对象中的新对象所取代如果对象的返回值不是对象,那么仍指向当前对象。

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。注意无论如何只有在存在外层代码才设置为这样:


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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78084.html

相关文章

  • JavaScript深入浅出

    摘要:理解的函数基础要搞好深入浅出原型使用原型模型,虽然这经常被当作缺点提及,但是只要善于运用,其实基于原型的继承模型比传统的类继承还要强大。中文指南基本操作指南二继续熟悉的几对方法,包括,,。商业转载请联系作者获得授权,非商业转载请注明出处。 怎样使用 this 因为本人属于伪前端,因此文中只看懂了 8 成左右,希望能够给大家带来帮助....(据说是阿里的前端妹子写的) this 的值到底...

    blair 评论0 收藏0
  • JavaScript this详解

    摘要:作为构造函数调用中没有类,但是可以从构造器中创建对象,并提供了运算符来进行调用该构造器。构造器的外表跟普通函数一样,大部分的函数都可以当做构造器使用。如果构造函数显式的返回一个对象,那么则会指向该对象。 this 的指向 this 是 js 中定义的关键字,它自动定义于每一个函数域内,但是它的指向却让人很迷惑。在实际应用中,this 的指向大致可以分为以下四种情况。 1.作为普通函数调...

    cyrils 评论0 收藏0
  • JavaScriptthis对象详解

    摘要:再来看一个小的示例淘宝腾讯淘宝为什么输出的依然是淘宝呢调用的是对象中的方法,方法里面有一个定时器,而定时器的一个参数是这里的指的就是的对象,然后方法里面有调用了,但是定时器中的指的是对象,所以最终调用的是对象中。 1.看前热身 看一段代码 var name = javascript; var obj = { name:js, foo:f...

    Integ 评论0 收藏0
  • javaScript原型及原型链详解(二)

    摘要:当然这还没完,因为我们还有重要的一步没完成,没错就是上面的第行代码,如果没有这行代码实例中的指针是指向构造函数的,这样显然是不对的,因为正常情况下应该指向它的构造函数,因此我们需要手动更改使重新指向对象。 第一节内容:javaScript原型及原型链详解(二) 第一节中我们介绍了javascript中的原型和原型链,这一节我们来讲利用原型和原型链我们可以做些什么。 普通对象的继承 ...

    widuu 评论0 收藏0
  • JavaScript apply 、call 的详解

    摘要:参数和是放在数组中传入函数,分别对应参数的列表元素。而原函数中的并没有被改变,依旧指向全局对象。保存原函数保存需要绑定的上下文剩余的参数转为数组返回一个新函数下一篇介绍闭包中闭包的详解。 apply 和 call 的区别 ECMAScript 规范给所有函数都定义了 call 与 apply 两个方法,它们的应用非常广泛,它们的作用也是一模一样,只是传参的形式有区别而已。 apply(...

    Meils 评论0 收藏0
  • javascriptnew关键字详解

    摘要:本文给大家详细介绍了下中关键字的使用方法,以及使用关键字的区别,有需要的小伙伴可以参考下。第行通过关键字创建了一个新对象行对象尝试访问和属性,并调用方法。一般情况下,函数对象在产生时会内置属性并将函数名作为赋值仅函数对象。 本文给大家详细介绍了下javascript中new关键字的使用方法,以及javascript 使用new关键字的区别,有需要的小伙伴可以参考下。 function ...

    alaege 评论0 收藏0

发表评论

0条评论

glumes

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<