“this”如何在构造函数中分配的函数中工作?

时间:2015-05-19 15:00:49

标签: javascript function constructor this

我找到了这个示例代码:

function personFullName() {
    return this.first + ' ' + this.last;
}

function Person(first, last) {
    this.first = first;
    this.last = last;
    this.fullName = personFullName;
}

var dude = new Person("Michael", "Jackson");
alert(dude.fullName());

警告“迈克尔杰克逊”。我将其更改为从构造函数中调用personFullName,而不是分配函数对象:

function personFullName() {
    return this.first + ' ' + this.last;
}

function Person(first, last) {
    this.first = first;
    this.last = last;
    this.fullName = personFullName();
}

var dude = new Person("Michael", "Jackson");
alert(dude.fullName);

我希望“fullName”属性现在是一个字符串而不是一个函数。但现在它警告“undefined undefined”。谁能解释为什么我的版本不起作用?

4 个答案:

答案 0 :(得分:6)

在JavaScript中,this通常是函数调用中.之前的任何内容。因此,您说dude.fullName()的原因是导致thisfullName()设置为dude 1 的原因。

在你问题的第二个版本中,你没有以同样的方式调用它。你正在调用personFullName()前面没有任何东西(这是正确的,因为它不再附加到Person对象)。这意味着this最终默认为与window相同的值。由于window上没有设置firstlast属性,this.firstthis.lastundefined

要解决此问题,您可以将您的人员作为personFullName()函数的参数:

function personFullName(person) {
    return person.first + ' ' + person.last;
}

然后将其称为

…
this.fullName = personFullName(this);

1:请注意,该方法必须是对象上的属性才能使this绑定起作用。您不能只是致电object.someMethod()并将this设置为object中的someMethod。在您的代码中,以下内容不起作用:

function Person(first, last) {
    this.first = first;
    this.last = last;
    this.fullName = this.personFullName();
}

Uncaught TypeError: this.personFullName is not a function

这两者都不会:

function personFullName() {
    return this.first + ' ' + this.last;
}

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

var dude = new Person("Michael", "Jackson");
alert(dude.personFullName());

Uncaught TypeError: dude.personFullName is not a function

您可以使用apply辅助方法在任何情况下解决此限制:this.fullName = personFullName.apply(this)执行您希望代码的第二个版本执行的操作,您也可以在personFullName.apply(dude)处调用"Michael Jackson"任何一点,然后回到<?= sprintf( __('bla bla bla <span id="count">%s</span> bla', true), $count ); ?>

答案 1 :(得分:1)

thispersonFullName函数中的窗口,因为它未在正确的上下文中调用。您可以使用apply使用正确的上下文调用它,而无需修改personFullName函数。

function personFullName() {
    return this.first + ' ' + this.last;
}

function Person(first, last) {
    this.first = first;
    this.last = last;
    this.fullName = personFullName.apply(this); // The magic
}

var dude = new Person("Michael", "Jackson");
alert(dude.fullName);

答案 2 :(得分:1)

更好的替代方法是:

Person.prototype.personFullName = function() {
    return this.first + ' ' + this.last;
}

答案 3 :(得分:0)

您在第二个示例中访问window的上下文是引用window对象。 fullName没有设置alert(this);属性。 如果你为这两个函数添加module Plugin1 def do_work p ['Plugin1', data] end end module Plugin2 def do_work p ['Plugin2', data] end end module Plugin3 def do_work p ['Plugin3', data] end end class Runner attr_accessor :data # Plugins need access to these. def initialize(data, *plugins) @data = data @plugin_names = plugins.map { |p| "Plugin#{p}" } end def run @plugin_names.each { |name| mod = Kernel.const_get(name) Runner.send(:include, mod) do_work } end end # Execute a runner using Plugin3 and Plugin1. r = Runner.new(987, 3, 1) r.run ,你就会明白我的意思。