JavaScript类符号和'this'关键字

时间:2016-04-13 17:36:40

标签: javascript class ecmascript-6 this

我知道在这个主题上还有其他一些问题,但似乎没有一个问题可以得出确凿的答案。

我正在构建一个HTML / CSS / JS移动应用程序,并且一直尝试使用以下符号样式来定义一些类:

样式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;
}());

这样做的好处是:

  • 成员变量是封装的,可以直接引用(例如没有this前缀)。
  • 我可以使用_instance变量,因此避免围绕this身份的歧义。
  • 符号相当干净且易读。

我还尝试了以下替代方案:

样式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();
};

样式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());
    }
}

但是,尽管有优势,我发现由于与this关键字相关的问题, B C 难以使用。也就是说,根据调用者this的上下文,可以引用类方法中的不同内容。此外,在这两种情况下,使用 A 中的_instance变量是不可能的,因为所有成员都需要以this.为前缀。< / p>

但是,正如评论中所指出的,样式A 在创建类的多个实例时不起作用。

编写此类的最佳方法是什么,但避免this的问题?

2 个答案:

答案 0 :(得分:2)

如果您想不惜一切代价避免使用具有后期绑定this的原型方法,可以在ES6中使用以下样式:

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

(您也可以使用function声明,但class的优势在于它可以阻止自动调用new

答案 1 :(得分:1)

您正在创建一个闭包,然后由 final Toolbar toolbar = (Toolbar) findViewById(R.id.actionbar); toolbar.setTitle(Html.fromHtml("<font color=#ffffff>" + getString(R.string.print_s) + "</font>")); toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.menu_icon)); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { DetailActivity.this.finish(); } }); toolbar.inflateMenu(R.menu.fav); toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { item.setIcon(R.drawable.back_icon) return true; } return false; } }); 构造函数在实例化对象之间共享闭包。它不会按预期工作。

Thing

在实例化对象之间共享私有空间是另一个主题,可以通过多种方式完成,例如我previous answer之一或类似

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