Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/474.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使用“self=this”和回调最简单的原型_Javascript_Class_Prototype - Fatal编程技术网

Javascript使用“self=this”和回调最简单的原型

Javascript使用“self=this”和回调最简单的原型,javascript,class,prototype,Javascript,Class,Prototype,我读过一些关于它的问题,但我仍然无法使它起作用: 以下是我的简化测试: var person = function(name, job) { var self = this; self.name = null; self.callMe = function() { alert(self.name + ' please!'); }; self.init = function() { self.name =

我读过一些关于它的问题,但我仍然无法使它起作用:

以下是我的简化测试:

var person = function(name, job)
{
    var self = this;
    self.name = null;

    self.callMe = function()
    {
        alert(self.name + ' please!');
    };

    self.init = function()
    {
        self.name = name;

        setTimeout(function(){self.callMe()}, 1000);
    }();
}

...

person.prototype.callMe = function()
{
    alert('Mister ' + this.name + ' please!');
};


var jonh = new person('john');
var joe = new person('joe');
您可以在此处进行测试:

1。为什么使用的
callMe()
函数是原来的函数?

我已经读到我必须使用
this
才能使用原型,这很有意义:因为我从
self.init()
调用存储在var
self
中的函数,存储在该var中的函数不会被我以后的原型修改。。。但是,如果我没有将
this
存储在
self
中,那么如何进行回调呢

2。如果我重写
callMe
person.callMe=function(){}它也会这样做,那么我为什么要使用prototype?

我还了解,将方法放置在原型中对性能有好处,因为它不会在每个实例中重复,而是在它们之间共享

谢谢你的教导

这就是原型遗传的工作原理。当callMe的回调返回时,代码尝试在回调的执行上下文中解析变量self。因为它没有在那里定义,所以它沿着原型链向上,发现它是在定义callMe和init函数的同一级别的执行上下文中定义的。由于callMe是在这个级别上定义的,所以它将简单地执行它。如果没有在这个级别上定义,它将执行在原型上定义的函数

2) 如果你想订阅OOJS,将函数放到原型上会清楚地表明它们是uhh“接口方法”。这里所做的是每次“新建”类时有效地定义实例方法

下面是如何将Person类实现为OO

var Person = function(name, job){
  this.name = name;
  this.init();
};

Person.prototype.init = function(){
  setTimeout((function() {
      this.callMe();
    }).apply(this), 1000);
};

Person.prototype.callMe = function(){
  alert('Mister ' + this.name + ' please!');
};

var jonh = new Person('john');
var joe = new Person('joe');

您的
self.callMe=function()
将关闭
person.prototype.callMe=function()
。。。因此,代码按预期运行
2。如果我像person.callMe=function(){}一样重写callMe;它也会这样做,那么我为什么要使用prototype?
不,它不会。这将
callMe
函数添加到
person
——这与
callMe
函数在
person
@JaromandaX实例上的功能不同。调用原始方法时,在alertcorrect中没有“Mister”,因为你在构造函数中输入了
prototype.callMe
,如果你定义了
person.prototype.callMe
,那么就不能输入
prototype.callMe
-哦,等等,
self.callMe
-因为设置超时回调谢谢你的回答,那么如何调用
person.prototype.callMe()
,如果有的话,从
person.init()
?@JaromandaX否它不会说
Uncaught TypeError:this.callMe不是一个函数
解析对象上的属性与执行上下文无关(这对于解析变量名很重要)。给定
self.name
,标识符self将在当前执行上下文中解析,如果未找到,则在(外部上下文的)范围链上解析,直到找到(或未找到)。如果找到了并且它是一个对象,则会检查该对象的属性是否有名称属性,如果没有找到,则在
[[Prototype]]]
链上查找,直到找到(或没有)。感谢@RobG的澄清that@antoni,我不小心删除了那把小提琴,下面是如何调用原型方法