2017-01-31 15 views
0

下記のコードからsaluteFriendsとsayHelloLaterメソッドにアクセスする際に助けが必要です。私はメソッドのスコープの間で混乱してきています。どちらかのメソッドがプライベートなのでアクセスできないので推測する。JavaScript - 関数にアクセスできません

function Person(name, friends) { 
     // friends is a list of strings 
     var say = function (sentence) { 
      console.log(name + ' says: ' + sentence); 
     }; 

     Person.prototype.sayHello = function (otherName) { 
      this.say('hello ' + otherName + '!'); 

     }; 

     this.saluteFriends = function() { 
      friends.forEach(function (friend) { 
       sayHello(friend); 
      }); 
     }; 

     this.sayHelloLater = function (delay, otherName) { 
      setTimeout(function() { 
       this.sayHello(otherName); 
      }, delay); 
     }; 
    } 

    var frnds = ["sam", "mathew"]; 
    var fcall = new Person("alan", frnds); 
    fcall.saluteFriends(); 
+0

'sayHello'関数はプロトタイプのプロパティの値です。あなたは単にsayHelloとしてそれを参照することによってそれを呼び出すことはできません。 – Pointy

答えて

0

差があり、プロトタイプ上の機能を一度作成し、各インスタンス間で共有され、代わりにためコンストラクタで作成された各新しいオブジェクト新しいオブジェクトとして作成あるコンストラクタで作成された関数の。

したがって、キーワードでプロトタイプ関数を呼び出すことはできません。さらに、say()関数をオブジェクトのプライベートメンバーとして宣言したので、thisキーワードは不要です。あなたの情報については

function Person(name, friends) { 
    // friends is a list of strings 
    var say = function (sentence) { 
     console.log(name + ' says: ' + sentence); 
    }; 

    Person.prototype.sayHello = function (otherName) { 
     //say function is a private function, no need of "this" keyword 
     say('hello ' + otherName + '!'); 

    }; 

    this.saluteFriends = function() { 
     friends.forEach(function (friend) { 
      //sayHello function is attached to the prototype, bind the context 
      this.sayHello(friend); 
     }.bind(this)); 
    }; 

    this.sayHelloLater = function (delay, otherName) { 
     setTimeout(function() { 
      this.sayHello(otherName); 
     }.bind(this), delay); 
    }; 
} 

var frnds = ["sam", "mathew"]; 
var fcall = new Person("alan", frnds); 
fcall.saluteFriends(); 
fcall.sayHelloLater(1000, "john"); 

、私は、私たちはclassarrow functionまたはstring interpolationを使用することを可能にする、ES2015で同じコードを作ってきました。また、矢印機能は自分自身を束縛しませんthis

class Person { 

    constructor(name, friends) { 
    this.name = name; 
    this.friends = friends; 
    } 

    say(sentence) { 
    console.log(`${this.name} says: ${sentence}`); 
    } 

    sayHello(otherName) { 
    this.say(`hello ${otherName}`); 
    } 

    saluteFriends() { 
    this.friends.forEach(friend => this.sayHello(friend)); 
    } 

    sayHelloLater(delay, otherName) { 
    setTimeout(() => this.sayHello(otherName), delay); 
    } 

} 

const person = new Person("paul", frnds); 
person.saluteFriends(); 
person.sayHelloLater(1000, "jack"); 
0
function Person(name, friends) { 
    // friends is a list of strings 
    this.say = function (sentence) { 
     console.log(name + ' says: ' + sentence); 
    }; 

    Person.prototype.sayHello = function (otherName) { 
     this.say('hello ' + otherName + '!'); 

    }; 

    this.saluteFriends = function() { 
     friends.forEach(function (friend) { 
      this.sayHello(friend); 
     }.bind(this)); 
    }; 

    this.sayHelloLater = function (delay, otherName) { 
     setTimeout(function() { 
      this.sayHello(otherName); 
     }, delay); 
    }; 
} 

var frnds = ["sam", "mathew"]; 
var fcall = new Person("alan", frnds); 
fcall.saluteFriends(); 

あなたは、作成されるオブジェクトのメソッドとして機能sayを添付する必要があります。だからvar saythis.sayに変更してください。 saluteFriendsforEachメソッドへの.bindthisのコンテキストが必要です。それ以外の場合は、thisの内のforEachはコールバック関数を指します。次にを呼び出す必要があります。thisをその前に置いてください。this.sayHello

関連する問題