Javascript私有/公共继承语法

Javascript私有/公共继承语法,javascript,inheritance,Javascript,Inheritance,我在Javascript中将私有/公共方法与继承相结合时遇到困难。我认为这只是我的一个误会,希望是一个简单的解决办法 以下是我所拥有的: RB = {}; RB.Fruit = function() { // Public this.getType = function() { return "FRUIT"; } } RB.Orange = function() { // Private function makeOrangeJuice

我在Javascript中将私有/公共方法与继承相结合时遇到困难。我认为这只是我的一个误会,希望是一个简单的解决办法

以下是我所拥有的:

RB = {};
RB.Fruit = function() {
    // Public
    this.getType = function() {
        return "FRUIT";
    }
}

RB.Orange = function() {

    // Private
    function makeOrangeJuice() {
        console.log("Orange has been squeezed.");
    }

    // Public
    return {
        getName : function() {
            return "Orange";
        }
    }
}
RB.Orange.prototype = new RB.Fruit();
var o = new RB.Orange();
console.log(o.getType());
当我运行这段代码时,我收到错误“uncaughttypeerror:Object”没有方法“getType”。我知道这与在类函数中使用“return”有关(因为将getName方法移出“return”块允许它工作),但我希望能够继续在类中声明私有/公共方法

如何修改它以允许RB.Orange访问RB.Fruit.getType函数


谢谢

在JavaScript中,构造函数调用隐式返回新构造的实例,但构造函数可以通过显式返回不同的对象来覆盖默认行为。例如,如果您这样定义“构造函数”
Foo

function Foo() {
    return new Date();
}
然后语句
foo=newfoo()
foo
设置为新的
日期,而不是新的
foo

如果我正确理解您的需求,您只需更改以下内容:

    return {
        getName : function() {
            return "Orange";
        }
    }
(在此情况下,“构造函数”返回一个完全新的对象,其中只有一个
getName
方法,并且与正在构造的对象没有任何关系)


(在JavaScript中,构造函数调用隐式返回新构造的实例,但构造函数可以通过显式返回不同的对象来覆盖默认行为)。例如,如果您这样定义“构造函数”
Foo

function Foo() {
    return new Date();
}
然后语句
foo=newfoo()
foo
设置为新的
日期,而不是新的
foo

如果我正确理解您的需求,您只需更改以下内容:

    return {
        getName : function() {
            return "Orange";
        }
    }
(在此情况下,“构造函数”返回一个完全新的对象,其中只有一个
getName
方法,并且与正在构造的对象没有任何关系)


(它向正在构造的对象添加一个
getName
方法,并且仍然允许返回该对象)。

以下是一种方法:

var RB = {};
RB.Fruit = function() {
    // Public
    this.getType = function() {
        return "FRUIT";
    }
}

RB.Orange = function() {
    // Private variable
    var fruit = new RB.Fruit();

    // Private function
    function makeOrangeJuice() {
        console.log("Orange has been squeezed.");
    }

    // Public object with accessor
    return {
        getName : function() {
            return "Orange";
        },
        getType: fruit.getType
    }
}

var o = new RB.Orange();
console.log(o.getType());

这里有一种方法可以做到这一点:

var RB = {};
RB.Fruit = function() {
    // Public
    this.getType = function() {
        return "FRUIT";
    }
}

RB.Orange = function() {
    // Private variable
    var fruit = new RB.Fruit();

    // Private function
    function makeOrangeJuice() {
        console.log("Orange has been squeezed.");
    }

    // Public object with accessor
    return {
        getName : function() {
            return "Orange";
        },
        getType: fruit.getType
    }
}

var o = new RB.Orange();
console.log(o.getType());

如果希望继承这些函数,则需要将其分配给对象的原型

RB = {};
RB.Fruit = function() {};
RB.Fruit.prototype.getType = function() {
    return 'Fruit';
};

RB.Orange = function() {};
RB.Orange.prototype = new RB.Fruit();
RB.Orange.prototype.getName = function() {
    return 'Orange';
};
如果您确实需要使用private,并且不能仅仅使用_名称之类的约定将事物标记为private,那么您需要将使用private的函数移动到具有private成员的构造函数中

如果它们不是特定于实例的,您可以(并且应该)用一个即时函数来包装整个过程

(function() {
    // All previous code here

    window.RB = RB;
}());

如果希望继承这些函数,则需要将其分配给对象的原型

RB = {};
RB.Fruit = function() {};
RB.Fruit.prototype.getType = function() {
    return 'Fruit';
};

RB.Orange = function() {};
RB.Orange.prototype = new RB.Fruit();
RB.Orange.prototype.getName = function() {
    return 'Orange';
};
如果您确实需要使用private,并且不能仅仅使用_名称之类的约定将事物标记为private,那么您需要将使用private的函数移动到具有private成员的构造函数中

如果它们不是特定于实例的,您可以(并且应该)用一个即时函数来包装整个过程

(function() {
    // All previous code here

    window.RB = RB;
}());
试试这个代码

RB = {};
RB.Fruit = function() {
    // Public
    this.getType = function() {
        return "FRUIT";
    }
}
RB.Fruit.prototype.getType = function() {
        return "FRUIT";
    };
RB.Orange = function() {
    RB.Fruit.call(this);
    // Private
    function makeOrangeJuice() {
        console.log("Orange has been squeezed.");
    }

    this.getName = function() {
            return "Orange";
        };
    this.getJuice = function(){
            makeOrangeJuice();
        };

};
var o = new RB.Orange();
//calling the super-call's function
console.log(o.getType());
//public function
o.getJuice();
//trying to access private function
o.makeOrangeJuice();
有关面向ojbect的javscript plz代码的更多详细信息,请查看下面的链接

试试这段代码

RB = {};
RB.Fruit = function() {
    // Public
    this.getType = function() {
        return "FRUIT";
    }
}
RB.Fruit.prototype.getType = function() {
        return "FRUIT";
    };
RB.Orange = function() {
    RB.Fruit.call(this);
    // Private
    function makeOrangeJuice() {
        console.log("Orange has been squeezed.");
    }

    this.getName = function() {
            return "Orange";
        };
    this.getJuice = function(){
            makeOrangeJuice();
        };

};
var o = new RB.Orange();
//calling the super-call's function
console.log(o.getType());
//public function
o.getJuice();
//trying to access private function
o.makeOrangeJuice();
有关面向ojbect的javscript plz代码的更多详细信息,请查看下面的链接

主要问题 当您从构造函数返回一个非原语值时,将返回该非原语值,而不是使用
new
关键字调用它时所期望的默认返回实例

例如

因此,您可以简单地将代码更改为:

RB.Orange = function() {

    // Private
    function makeOrangeJuice() {
        console.log("Orange has been squeezed.");
    }

    this.getName = function ()  {
        return 'Orange';
    };

    //priviledged function which uses a private member
    this.someOtherFunction = function () {
        makeOrangeJuice();
    };
};
代码中的一些低效之处 为什么不使用
原型
? 不应在构造函数中声明没有特权的函数。换句话说,不访问私有变量的函数不应该在构造函数中创建,因为它们不必这样做,这样做效率极低。为什么?因为每次调用构造函数时都会创建一个新函数

相反,您应该使用构造函数.prototype在所有实例之间共享您的公共函数

例如

使用
对象。尽可能为继承创建
而不是
新建
。 大多数使用
new
关键字的继承模式都是这样做的,因为该语言缺少另一种方法来设置对象的原型链,但是现在我们有了
object.create
,您应该使用它。使用
new
关键字进行继承会产生一些不希望的副作用,比如运行构造函数。有一些方法可以通过使用中间空函数来避免这些副作用,但为什么不简单地使用
Object.create

例如(基于上述示例)

私人功能也可以共享! 请注意,不访问私有变量的私有函数也可以共享。您可以使用模块模式为它们创建一个作用域

例如

主要问题 当您从构造函数返回一个非原语值时,将返回该非原语值,而不是使用
new
关键字调用它时所期望的默认返回实例

例如

因此,您可以简单地将代码更改为:

RB.Orange = function() {

    // Private
    function makeOrangeJuice() {
        console.log("Orange has been squeezed.");
    }

    this.getName = function ()  {
        return 'Orange';
    };

    //priviledged function which uses a private member
    this.someOtherFunction = function () {
        makeOrangeJuice();
    };
};
代码中的一些低效之处 为什么不使用
原型
? 不应在构造函数中声明没有特权的函数。换句话说,不访问私有变量的函数不应该在构造函数中创建,因为它们不必访问,而且是ext