Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 添加原型链2层深_Javascript - Fatal编程技术网

Javascript 添加原型链2层深

Javascript 添加原型链2层深,javascript,Javascript,考虑以下代码: var Test = function(name) { this.member = name; } Test.prototype.perform = function() { console.log(this); }; Test.prototype.perform.prototype.dance = function() { console.log(this); }; var actor = new Test('jane'); actor.perfo

考虑以下代码:

var Test = function(name) {
    this.member = name;
}

Test.prototype.perform = function() {
    console.log(this);
};

Test.prototype.perform.prototype.dance = function() {
    console.log(this);
};

var actor = new Test('jane');
actor.perform();
actor.perform.dance();

我希望能够添加要执行的方法。当我在perform方法内部控制台.log(此)时,我可以看到dance方法已添加到原型链中,perform可以访问所有内容(我可以访问
this.member
),但当我在dance方法内部注销
this
时,它只返回一个如下所示的对象:

Object {dance: function} 
它似乎以某种方式失去了访问父级的权限,现在我再也无法访问
此.member


为什么会这样?难道不能像我上面所做的那样向原型中添加方法吗?

如果您这样调用它,它将起作用-

actor.perform.prototype.dance()
以这一行为例:

Test.prototype.perform = function() {
    console.log(this);
};
这意味着,每当有人使用
new Test()
创建一个对象时,它的原型(不能在所有浏览器中以统一的方式访问,chrome支持非标准的
\uuuuuuu proto\uuuu
访问器)将设置为
Test
prototype
属性。因此,您可以访问
perform
方法

现在:

Test.prototype.perform.prototype.dance = function() {
    console.log(this);
};
告诉表示,
perform
已添加到
Test
prototype
属性中,其本身具有另一个名为
prototype
的属性,该属性具有另一个名为
dance
的属性,其中包含所需的方法

如果你这样做-

Test.prototype.perform.dance = function () {....}
然后这意味着添加到
Test
prototype
属性的
perform
有一个名为dance的属性,该属性指向一个函数。由于
actor
对象的原型(同样,只能使用
\uuuuu proto\uuuu
以非标准方式访问)被设置为
测试的
prototype
属性,因此您可以通过以下方式访问它-

actor.perform.dance();

希望这能为你净化空气。

Test.prototype.perform.prototype.dance
更改为
Test.prototype.perform.dance

actor.perform.dance()将起作用

actor.perform.dance();
当您执行此操作且所有函数都未绑定时,
内部舞蹈将指向
演员。执行
。您希望它指向
actor
。有两种方法可以实现这一点:

解决方案1:使用正确的this:

actor.perform.dance.call(actor);
var Test = function(name) {
    this.member = name;

    this.perform = function() {
        console.log(this);
    };

    this.perform.dance = function() {
        console.log(this);
    }.bind(this); 
}
优点:您可以保持声明不变

缺点:你必须在任何你称之为舞蹈的地方这样做

解决方案2:声明方法时绑定该方法:

actor.perform.dance.call(actor);
var Test = function(name) {
    this.member = name;

    this.perform = function() {
        console.log(this);
    };

    this.perform.dance = function() {
        console.log(this);
    }.bind(this); 
}
优点:您可以保持调用代码不变(
actor.perform.dance()

缺点:将为每个参与者创建一些新函数(它们不能在原型上共享)

编辑:解决方案3:委派功能

我不打算给出代码,因为这更难,但主要思想是这样的

您可以创建另一个类(Performance),该类具有必要的方法和
target
属性。您的
Test.prototype.perform()
方法返回一个性能实例,其目标属性设置为调用它的测试实例。表演的舞蹈方法是针对目标的,而不是针对这个目标。由您决定Test perform方法是在每次调用时创建一个新实例,还是在每次为特定测试实例调用时返回相同的实例

优点:没有为每个实例创建更多的函数。不需要记住用正确的方法来称呼舞蹈


缺点:复杂性。

我已经重新表述了这个问题。问题是dance没有访问父实例的权限vars@MikeRifgin当前位置我也编辑了我的答案。如果您仍有疑惑,请回复。舞蹈方法无权访问此.member。有没有什么方法可以编写这样的代码,使原型舞蹈能够访问与表演相同的上下文?