JavaScript - 就是这个

时间:2011-04-21 23:59:58

标签: javascript oop

String.prototype.foo = {};
String.prototype.foo.bar = function() {
    //How can you reference the "grandparent" string?
    console.log(this.parent.parent); //obviously, doesn't exist
}

如同,"Hello, Nurse!".foo.bar()会记录“你好,护士!”。

如果对foo有控制权会不会有所作为?

编辑:在那里,定义了foo。

Edit2:很好,而不是this.this.thisthis.parent.parent。当然父母不存在,但希望现在语义不会妨碍。

编辑3:没有具体案例。提供的细节几乎都是我得到的:有一个对象foo,原型的一部分。 foo.barfoo的一种方法,应该访问其祖父母。而已。没有其他的。这就是我的所有信息。

Edit4:已解决。根据提供的答案(以及Douglas Crockford的一些二手帮助):

String.prototype.foo = function() {
    var that = this;
    return {
        bar : function() {
            console.log(that.valueOf());
        }
    }
}
//Called:
"Hello, Nurse!".foo().bar();

2 个答案:

答案 0 :(得分:7)

这可以做到的唯一方法是将foo()变成一个函数。可以将其视为初始化特定字符串的foo命名空间:

String.prototype.foo = function () {
    var str = String(this);
    var o = Object(this)
    o.bar = function () {
         console.log(str);
    };
    return o;
};

然后你可以使用:

"foobar".foo().bar(); // logs "foobar"

或者,如果我们将foobar重命名为更令人兴奋的内容:

"Hello!".console().log(); // logs "Hello!"

为什么这么复杂?

使用特定的上下文(每个对象)调用每个函数。无论是使用a.b()还是a.b.c.d()调用它都无关紧要 - 它会立即将函数调用的作为其上下文。因此a.b()的上下文为aa.b.c.d()的上下文为c。关键字this引用上下文。由于c只是对象(不是正在运行的函数),因此它没有上下文,并且没有this的概念,因此this.this没有意义。

因此,不可能一般地访问所谓的“父母”。胡安的回答给出了一个很好的概念解释原因。但是,如果你想要实现的是原型函数中的命名空间,那么可以通过从foo返回一个增强对象来实现这一点。

注意我还必须将this转换为上面的Object。这是因为您无法将属性附加到原始值(如字符串)。 var str = "foo"; str.bar = 1将起作用,但仅限于JS自动将"foo"转换为对象。但是,由于str引用了原语,而不是自动创建的对象,因此该对象立即被丢弃,我们将丢失bar

答案 1 :(得分:3)

对象无法知道它是什么对象的属性。可以将同一对象(在您的情况下为函数)附加到多个对象。这是一个例子:

var myObj = {};
var objA = {prop: myObj};
var objB = {nother: myObj}

如果给出myObj的引用,你怎么可能知道你指的是哪个父对象?在一个案例中,它没什么,另一种情况,它是objA,最后一种情况,它是objB的“子”对象。如果你解释为什么你喜欢这种行为,我们可以帮助你解决手头的问题。但问题的答案是你不能这样做。