如何在javascript中用类中的对象包装函数?

Joh*_*euk 3 javascript oop function object javascript-objects

假设我有一个名为的课程Human.

function Human(name, gender, age, personality){
    this.name = name;
    this.gender = gender;
    this.age = age;
    this.personality = personality; 
}
Run Code Online (Sandbox Code Playgroud)

我有一些类的功能,如greetingintroduce.所以我创建它们是这样的:

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!");
}
Run Code Online (Sandbox Code Playgroud)

由于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;
        }
}
Run Code Online (Sandbox Code Playgroud)

现在的问题是,当一个函数被一个对象包装时,this在introduction函数中不再引用该实例.那我怎么能解决这个问题呢?

我想把这个函数称为:

var eminem = new Human("Marshall Mathers", "M", 45, "aggressive");
eminem.speak.introduce();
Run Code Online (Sandbox Code Playgroud)

Rom*_*man 5

和一个人说话

创建Speak一个类,因为OOP中的变量和功能的逻辑分组是类.

说话

function Speak(human) {
    this.human = human
}

Speak.prototype.greeting = function () {
    // ...
}

Speak.prototype.introduce = function () {
    // ..
}
Run Code Online (Sandbox Code Playgroud)

人的

function Human(name, gender, age, personality, greetWord) {
    this.name = name;
    this.gender = gender;
    this.age = age;
    this.personality = personality;
    this.speak  = new Speak(this)
}
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)


解决方案的另一种方法是使用apply.

应用

apply()方法使用给定的此值调用函数,并将参数作为数组(或类数组对象)提供.

var peter = new Human('Peter', 'M', 35, 'aggressive')
console.log(peter.speak.introduce.apply(peter))
Run Code Online (Sandbox Code Playgroud)

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))
Run Code Online (Sandbox Code Playgroud)