简体   繁体   English

JavaScript类表示法和'this'关键字

[英]JavaScript class notation and the 'this' keyword

I'm aware there have been a few other questions on this topic, but none of them seem to give a conclusive answer. 我知道在这个主题上还有其他一些问题,但是他们似乎都没有给出确凿的答案。

I'm building a HTML/CSS/JS mobile app, and have been trying the following style of notation to define some classes: 我正在构建一个HTML / CSS / JS移动应用程序,并且一直在尝试使用以下样式的符号来定义一些类:

Style A 风格A.

var Thing = (function ()
{
    var _instance;

    var _firstName;
    var _lastName;

    function Thing(firstName, lastName)
    {
        _instance = this;

        _firstName = firstName;
        _lastName = lastName;
    }

    Thing.prototype.getMyName = function ()
    {
        return _firstName + " " + _lastName;
    }

    Thing.prototype.speak = function ()
    {
        return ("My name is " + _instance.getMyName());
    }

    return Thing;
}());

The advantages of this are: 这样做的好处是:

  • Member variables are encapsulated and can be referred to directly (eg without the this prefix). 成员变量是封装的,可以直接引用(例如没有this前缀)。
  • I can use the _instance variable and therefore avoid ambiguity around the identity of this . 我可以使用_instance变量,因此避免了this身份的歧义。
  • The notation is reasonably clean and readable. 符号相当干净,可读。

I also gave the following alternatives a try: 我还尝试了以下替代方案:

Style B 风格B.

function Thing(firstName, lastName)
{
    this._firstName = firstName;
    this._lastName = lastName;
}

Thing.prototype.getMyName = function()
{
    return this._firstName + " " + this._lastName;
};

Thing.prototype.speak = function()
{
    return "My name is " + this.getMyName();
};

Style C 风格C.

class Thing
{
    constructor (firstName, lastName)
    {
        this._firstName = firstName;
        this._lastName = lastName;
    }

    getMyName ()
    {
        return this._firstName + " " + this._lastName;
    }

    speak ()
    {
        return ("My name is " + this.getMyName());
    }
}

But despite their advantages, I have found B and C difficult to work with because of problems associated with the this keyword; 但是尽管有这些优点,我发现BC很难处理,因为this关键字存在问题; that is, depending on the context of the caller this can refer to different things within the class methods. 也就是说,根据调用者的上下文, this可以引用类方法中的不同内容。 Furthermore in both these cases, using an _instance variable as I have in A is not possible because all members need to prefixed with this. 此外,在这两种情况下,使用我在A中_instance变量是不可能的,因为所有成员都需要以此为前缀this. .

However, as pointed out in the comments, Style A does not work when multiple instances of the class are created. 但是,正如注释中所指出的, 样式A在创建类的多个实例时不起作用。

What's the best way to write such classes but avoid problems with this ? 什么是写这样的类,但避免问题的最好办法this

If you want to avoid prototype methods with late-bound this at all costs, you can use the following style in ES6: 如果你想避免原型方法与后期绑定this不惜一切代价,你可以使用下面的风格在ES6:

class Thing {
    constructor(firstName, lastName) {
        this.getMyName = () => firstName + " " + lastName;
        this.speak = () => "My name is " + this.getMyName();
    }
}

(you can also use a function declaration, but the class has the advantage that it prevents calls without new automatically) (你也可以使用一个function的声明,但class都有,它可以防止通话,而利用new自动)

You are creating a closure and then sharing the closure among instantiated objects by the Thing constructor. 您正在创建一个闭包,然后由Thing构造函数在实例化对象之间共享闭包。 It will not work as intended. 它不会按预期工作。

var elton = new Thing("Elton", "Johnnavartangula");
elton.getMyName(); // <- "Elton Johnnavartangula"
var fenry = new Thing("Fenry", "Honda");
elton.speak(); // <- "My name is Fenry Honda"

sharing privates among instantiated objects is another topic and can be done in several ways like in one of my previous answer or like 在实例化对象之间共享私有部分是另一个主题,可以通过几种方式完成,例如我之前的答案之一

function Source(){
var priv = "secret";
return {gp : function(){return priv},
        sp : function(v){priv = v}
       }
}
sharedProto = Source(); // priv is now under closure to be shared
var p1 = Object.create(sharedProto); // sharedProto becomes o1.__proto__
var p2 = Object.create(sharedProto); // sharedProto becomes o2.__proto__

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM