我们说我有一个名为Human
的课程。
function Human(name, gender, age, personality){
this.name = name;
this.gender = gender;
this.age = age;
this.personality = personality;
}
我有一些类的功能,例如greeting
和introduce
。所以我像这样创建它们:
Human.prototype.introduce = function() {
var _gender = {"M": "Boy", "F": "Girl"};
switch(this.personality)
{
case "passionate":
alert("Hi, how are you? My name is " + this.name + ". I'm " + this.age + " years old " + _gender[this.gender] + ". ");
break;
case "aggressive":
alert("I'm " + this.name + ". What you want? ");
break;
}
}
Human.prototype.greeting = function() {
alert("Hi!");
}
由于introduce
和greeting
可以按相同的类别进行分组(让我们将其命名为speak
),我怎样才能简单地用对象包装这两个函数?我试过这个:
Human.prototype.speak = {};
Human.prototype.speak.greeting = function(){
alert("Hi!");
}
Human.prototype.speak.introduce = function(){
var _gender = {"M": "Boy", "F": "Girl"};
switch(this.personality)
{
case "passionate":
alert("Hi, how are you? My name is " + this.name + ". I'm " + this.age + " years old " + _gender[this.gender] + ". ");
break;
case "aggressive":
alert("I'm " + this.name + ". What you want? ");
break;
}
}
现在的问题是,当一个函数被一个对象包装时,introduction函数中的this
不再引用该实例。那么我该如何解决这个问题呢?
我想把这个函数称为:
var eminem = new Human("Marshall Mathers", "M", 45, "aggressive");
eminem.speak.introduce();
答案 0 :(得分:5)
使Speak
成为一个类,因为OOP中的变量和功能的逻辑分组是类。
function Speak(human) {
this.human = human
}
Speak.prototype.greeting = function () {
// ...
}
Speak.prototype.introduce = function () {
// ..
}
function Human(name, gender, age, personality, greetWord) {
this.name = name;
this.gender = gender;
this.age = age;
this.personality = personality;
this.speak = new Speak(this)
}
function Human(name, gender, age, personality, greetWord) {
this.name = name;
this.gender = gender;
this.age = age;
this.personality = personality;
this.greetWord = greetWord;
this.speak = new Speak(this)
}
function Speak(human) {
this.human = human
}
Speak.prototype.greeting = function () {
alert(this.human.greetWord + "!");
}
Speak.prototype.introduce = function () {
var _gender = { "M": "Boy", "F": "Girl" };
switch (this.human.personality) {
case "passionate":
alert("Hi, how are you? My name is " + this.human.name + ". I'm " + this.human.age + " years old " + _gender[this.human.gender] + ". ");
break;
case "aggressive":
alert("I'm " + this.human.name + ". What you want? ");
break;
}
}
var peter = new Human('Peter', 'M', 35, 'aggressive', 'Hi')
peter.speak.greeting()
peter.speak.introduce()

解决方案的另一种方法是使用apply。
apply()方法调用具有给定值的函数,并将参数作为数组(或类数组对象)提供。
var peter = new Human('Peter', 'M', 35, 'aggressive')
console.log(peter.speak.introduce.apply(peter))
function Human(name, gender, age, personality){
this.name = name;
this.gender = gender;
this.age = age;
this.personality = personality;
}
Human.prototype.speak = {};
Human.prototype.speak.greeting = function(){
alert("Hi!");
}
Human.prototype.speak.introduce = function(){
var _gender = {"M": "Boy", "F": "Girl"};
switch(this.personality)
{
case "passionate":
alert("Hi, how are you? My name is " + this.name + ". I'm " + this.age + " years old " + _gender[this.gender] + ". ");
break;
case "aggressive":
alert("I'm " + this.name + ". What you want? ");
break;
}
}
var peter = new Human('Peter', 'M', 35, 'aggressive')
console.log(peter.speak.introduce.apply(peter))

答案 1 :(得分:3)
您可以bind
在其构造函数
this
的上下文
function Human(name, gender, age, personality){
this.name = name;
this.gender = gender;
this.age = age;
this.personality = personality;
this.speak.introduce = this.speak.introduce.bind(this);
}
这样,this
函数中的introduce
将始终是Human
的当前实例
答案 2 :(得分:1)
function Human(name, gender, age, personality){
this.name = name;
this.gender = gender;
this.age = age;
this.personality = personality;
var self = this; //this is how
this.speak = {
introduce: function() {
var _gender = {"M": "Boy", "F": "Girl"};
switch(self.personality)
{
case "passionate":
alert("Hi, how are you? My name is " + self.name + ". I'm " + self.age + " years old " + _gender[self.gender] + ". ");
break;
case "aggressive":
alert("I'm " + self.name + ". What you want? ");
break;
}
},
greeting: function() {
alert("Hi!");
}
};
}
var hulk = new Human("Hulk", "M", 33, "aggressive");
hulk.speak.introduce();
答案 3 :(得分:1)
根据接受的答案,您可以编写几行代码,使用Object.keys和forEach自动重新绑定所有函数。
function Human(name, gender, age, personality){
this.name = name;
this.gender = gender;
this.age = age;
this.personality = personality;
Object.keys(this.speak).filter(function(key) {
return typeof this.speak[key] === 'function';
}, this).forEach(function(key) {
this.speak[key] = this.speak[key].bind(this);
}, this);
}
此外,您可以轻松改进此代码,不仅可以迭代“说话”的功能。对象