当前位置:  开发笔记 > 编程语言 > 正文

JavaScript中'this'关键字行为的基本原理是什么?

如何解决《JavaScript中'this'关键字行为的基本原理是什么?》经验,为你挑选了2个好方法。

我从语言设计的角度来问这个问题.所以我试图找出答案

    这种行为的理由是this什么?

    这种行为在何种程度上this是错误的,或者可以改进?


为了澄清我为什么不安this,请考虑这个例子:

var a = {};
a.f = function(){ return this; }
var f = a.f;
// f() != a.f()

请注意遗留的对象f()是多么容易丢失:与之分离a,this成为全局对象(window对于浏览器).

现在考虑:

var newA = function(){
    var self = {};
    self.f = function(){ return self; }
    return self;
}

var a = newA();
var f = a.f;
// f() == a.f() !

this在完全不使用的情况下,无论方法在何处或如何使用,我们都能够建立和维护对象上下文.我不禁想到,凭借封闭所提供的力量,this变得多余,甚至可能有点危险......

我不是在反对某些仇杀this,或者想要开始争论; 我只是想更好地理解它.我确实理解"这个"可能很有用,但也认识到它也可能令人困惑 ......当然,对于初学者而言,也许对专家来说也会让人感到困惑.

然而,在该语言的其他核心方面看起来像是回避公平游戏(即Crockford和withor new)时,它仍然是一种经常使用且看似备受尊重的语言部分.那么我想念的是什么,这是this不可或缺的?



1> Shog9..:

您似乎期望它的行为与某些OO语言中的行为一样,它始终引用方法所属的对象.

但是在JavaScript中,函数可以附加到多个对象,或者根本不附加任何对象.在您的示例中,您编写了一个旨在用于某个特定对象的上下文的函数 ......但是没有什么能阻止我将该函数与其他任何对象相关联.这只是语言的本质 - 函数是一流的,对象成员资格是可选的.

因此,指的是调用函数的上下文.眼下,这两种的任意对象(通过指定.,.apply.call())或全局对象.在该语言的未来版本中,它将引用定义函数的上下文:全局函数的全局对象this,内部函数的外部对象; 你可以将其视为设计缺陷的修正,因为实际上能够使用它来引用全局对象并不是特别有用.



2> Matthew Crum..:

我不认为让"这个"不受约束是一个错误.起初它有时会让人感到困惑,但它有很好的理由.首先想到的是,由于JavaScript不是基于类的语言,因此函数不与任何特定类相关联,因此没有一种将"this"自动绑定到正确对象实例的一致方法.例如,

function Person(first, last, age) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
}

Person.prototype.getFullName = function() {
    return this.firstName + " " + this.lastName;
};

"this"需要引用Person对象,但是分配给Person.prototype.getName的函数没有任何方法可以知道它将如何被使用,所以"this"需要被绑定到它所调用的任何对象上.

如果这会导致问题,那就是当你有嵌套函数时.

// This is a really contrived example, but I can't think of anything better
Person.prototype.getInfo = function() {
    // get name as "Last, First"
    function getNameLastFirst() {
        // oops. "this" is the global object, *not* the Person
        return this.lastName + ", " + this.firstName;
    }

    // expect something like "Crumley, Matthew: Age 25",
    // but you get "undefined, undefined: Age 25"
    return getNameLastFirst() + ": Age " + this.age;
};

提出的语法artificialidiot很方便,但使用apply将"this"绑定到特定对象非常容易:

function bind(func, obj) {
    return function() {
        return func.apply(obj, arguments);
    };
}

Person.prototype.getInfo = function() {
    // get name as "Last, First"
    var getNameLastFirst = bind(function () {
        return this.lastName + ", " + this.firstName;
    }, this);

    return getNameLastFirst() + ": Age " + this.age;
};

或者使用闭包的更"传统"的方法:

Person.prototype.getInfo = function() {
    var self = this;

    // get name as "Last, First"
    function getNameLastFirst() {
        return self.lastName + ", " + self.firstName;
    }

    return getNameLastFirst() + ": Age " + this.age;
};

推荐阅读
雨天是最美
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有