你能在JavaScript中继承私有函数吗?

css*_*sss 10 javascript

我正在使用一个闭包来创建一个私有和公共方法的对象.它看起来像这样 -

var Dog = (function() {
    function Dog() {}

    var size = 'big';

    var _privateSaySize = function() {
        return 'I am a ' + size + ' dog.';
    }

    Dog.prototype.publicSaySize = function() {
        return _privateSaySize();
    }

    return Dog;
})();
Run Code Online (Sandbox Code Playgroud)

但是现在我希望有一个只有私有函数并且由另一个对象继承的对象.但这在JavaScript中是否可行?

Rad*_*nik 8

不,你不能.

JavaScript继承是基于原型的,因此您只能"扩展"原型中的方法.


Ber*_*rgi 5

JavaScript中变量(函数)的隐私是通过函数范围完成的.只有从封闭范围导出它们才能从外部访问它们,没有其他办法.

要创建一个方法可以访问私有函数的对象,您只需将它放在同一范围内.对象是否是从其他对象继承的对象是无关紧要的.

function Dog() {}
function Dalmatian() {}
Dalmation.prototype = Object.create(Dog.prototype);
Dalmation.prototype.size = "big";
function Dackel() {}
Dackel.prototype = Object.create(Dog.prototype);
Dackel.prototype.size = "small";

(function() {
    // private function
    function say(s) {
        console.log("I'm a "+s+" dog");
    }
    // both accessible from the Dog and Dackel public methods
    Dog.prototype.saySize = function() {
        say(this.size || "normal");
    };
    Dackel.prototype.saySize = function() {
        say(this.size + " but loud");
    };
})();
new Dog().saySize();
new Dalmatian().saySize();
new Dackel().saySize();
Run Code Online (Sandbox Code Playgroud)


Aad*_*hah 1

您希望一个实例继承另一个实例的私有状态吗?当然你可以在 JavaScript 中做到这一点。首先我们需要定义一个效用函数:

function weakBind(functable, prototype, state) {
    return function () {
        return functable.apply(this, Object.getPrototypeOf(this) === prototype ?
            [state].concat(Array.prototype.slice.call(arguments)) : arguments);
    };
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以创建我们的基类,如下所示:

var Dog = (function () {
    function Dog() {
        if (this instanceof Dog) {
            // constructor code
        } else return Object.create(private);
    }

    var public = Dog.prototype, private = Object.create(public, {
        size: {
            value: "big"
        }
    });

    public.saySize = weakBind(function (private) {
        return "I am a " + private.size + " dog.";
    }, public, private);

    return Dog;
}());
Run Code Online (Sandbox Code Playgroud)

现在你可以创建一只狗,如下所示:

var dog = new Dog;
alert(dog.saySize()); // I am a big dog.
alert(dog.size);      // undefined
Run Code Online (Sandbox Code Playgroud)

我们可以如下继承私有状态:

var Chihuahua = (function () {
    function Chihuahua() {
        Dog.call(this);
    }

    var private = Dog();

    Object.defineProperty(private, {
        size: {
            value: "small"
        }
    });

    var public = Chihuahua.prototype = Object.create(Dog.prototype);

    public.saySize = weakBind(public.saySize, public, private);

    return Chihuahua;
}());
Run Code Online (Sandbox Code Playgroud)

现在您可以按如下方式创建吉娃娃:

var chi = new Chihuahua;
alert(chi.saySize());    // I am a small dog.
alert(chi.size);         // undefined
Run Code Online (Sandbox Code Playgroud)

请参阅演示:http://jsfiddle.net/b3Eyn/

注意:我写这个答案只是为了表明可以在 JavaScript 中继承私有状态。不过我建议你不要使用这种模式。如果您设计得很好,那么您首先就不需要继承私有状态。