JavaScript中的私有继承 < > C++中的继承是用访问指定符公共< /代码>、保护< /COD>和私下< /代码>来指定的。私有继承使基类的公共成员和受保护成员成为派生类的私有成员

JavaScript中的私有继承 < > C++中的继承是用访问指定符公共< /代码>、保护< /COD>和私下< /代码>来指定的。私有继承使基类的公共成员和受保护成员成为派生类的私有成员,javascript,inheritance,prototype,Javascript,Inheritance,Prototype,有没有办法在JavaScript中实现私有继承 我知道JavaScript有基于原型的继承,所以我很困惑是否有办法使基类的公共成员成为派生类的私有成员。JavaScript中任何对象的私有成员都是在函数中定义的,该函数将对象本身创建为函数的变量,因此,由于Clousure,这些变量只在对象的方法中可见,这些方法引用了这些变量 function Person (age) { var age = age; this.name = 'Robert'; this.isAdult = func

有没有办法在JavaScript中实现私有继承


我知道JavaScript有基于原型的继承,所以我很困惑是否有办法使基类的公共成员成为派生类的私有成员。

JavaScript中任何对象的私有成员都是在函数中定义的,该函数将对象本身创建为函数的变量,因此,由于Clousure,这些变量只在对象的方法中可见,这些方法引用了这些变量

function Person (age) {
  var age = age;
  this.name = 'Robert';
  this.isAdult = function () {
    return age > 17;
  };
}
在上面的代码中,age“property”是私有的,所以它是私有的,实际上无法修改,您唯一能做的就是使用isAdult方法检查它是否大于17


在子类构造函数中实现这一点几乎是一样的,您只需要定义原型的属性,而不希望将其作为构造函数函数中的变量设置为private,并在构造函数函数中定义有权访问该属性的对象的方法。

基类的实例属性在派生类构造函数调用时继承基类构造函数。此时,需要私下继承的基类的所有实例属性可以作为局部变量存储在派生类的构造函数中,然后从派生类的实例中删除

这种技术显然不适用于从基类原型继承的属性。然而,这服务于我的用例,因此我在这里分享它

在下面的示例中,派生类
ChocolateCake
私下继承了基类
Cake
的成员
setBakingTemperature

function Cake() {
    var bakingTemperature = 250;
    this.setBakingTemperature = function(temperature) {
        bakingTemperature = Math.min(temperature, 400);
    }
    this.getBakingTemperature = function() {
        return bakingTemperature;      
    }
}

Cake.prototype.bake = function() {
    console.log("Baking the cake at " + this.getBakingTemperature() + " °C");
}

function ChocolateCake() {
    Cake.call(this);

    /* inherit 'setBakingTemperature' privately */
    var setBakingTemperature = this.setBakingTemperature;
    delete this.setBakingTemperature;

    setBakingTemperature(300);
}

ChocolateCake.prototype = Object.create(Cake.prototype, {
    constructor: {value: ChocolateCake}
});


var chocolateCake = new ChocolateCake();
chocolateCake.setBakingTemperature(); /* throws TypeError exception */
chocolateCake.getBakingTemperature(); /* 300 */
chocolateCake.bake(); /* Baking the cake at 300 °C */
更新:

使用@idea,还有另一种方法可以实现这一点。这种方法的优点是,子类可以选择要从基类继承的属性,并且不需要关心其他属性

var Cake = function() {
    var bakingTemperature = 250;
    var setBakingTemperature = function(temperature) {
        bakingTemperature = Math.min(temperature, 400);
    }
    this.inheritSetBakingTemperature = function() {
        if (this instanceof Cake) {
            return setBakingTemperature;
        }
        return null;
    }
    this.getBakingTemperature = function() {
        return bakingTemperature;
    }
}

Cake.prototype.bake = function() {
    console.log("Baking the cake at " + this.getBakingTemperature() + " °C");
}

var ChocolateCake = function() {
    Cake.call(this);

    /* inherit 'setBakingTemperature' privately */
    var setBakingTemperature = this.inheritSetBakingTemperature();

    setBakingTemperature(300);
}

ChocolateCake.prototype = Object.create(Cake.prototype, {
    constructor: {value: ChocolateCake}
});

var chocolateCake = new ChocolateCake();
chocolateCake.setBakingTemperature(); /* throws TypeError exception */
chocolateCake.getBakingTemperature(); /* 300 */
chocolateCake.bake(); /* Baking the cake at 300 °C */

这说明C++风格的“公共”、“保护”和“私有”数据成员和成员函数。

function Base() {
  'use strict';
  /*--------------------------------------------------------------------------*/
  /*Declare all data members here using 'this.' which makes them 'public', but
  only in the scope of Base.                                                  */
  function Core() {
    this.private_data1 = 'private data1 of Base';
    this.private_data2 = 'private data2 of Base';
    this.protected_data1 = 'protected data1 of Base';
    this.protected_data2 = 'protected data2 of Base';
    this.public_data1 = 'public data1 of Base';
    this.public_data2 = 'public data2 of Base';
  }
  /*--------------------------------------------------------------------------*/
  /*Declare all member function here using 'Core.prototype.' which makes them
  'public' too, but again only in the scope of Base.                          */
  Core.prototype.private_function1 = function() {
    console.log('private function1 of Base.');
  };
  Core.prototype.private_function2 = function() {
    console.log('private function2 of Base.');
  };
  Core.prototype.protected_function1 = function() {
    console.log('protected function1 of Base.');
  };
  Core.prototype.protected_function2 = function() {
    console.log('protected function2 of Base.');
  };
  Core.prototype.public_function1 = function() {
    console.log('public function1 of Base.');
    /*We can call public, protected and private functions ...*/
    this.protected_function1();
    this.private_function1();
    /*... and access public, protected and private from here ...*/
    console.log(this.public_data1);
    console.log(this.protected_data1);
    console.log(this.private_data1);
    /*... even if they're overloaded.*/
    this.public_function2();
    this.protected_function2();
    this.private_function2();
    console.log(this.public_data2);
    console.log(this.protected_data2);
    console.log(this.private_data2);
  };
  Core.prototype.public_function2 = function() {
    console.log('public function2 of Base.');
  };
  /*--------------------------------------------------------------------------*/
  /*Define visibility of the members. If you're editing the core, make sure that
  each member is listed in no more and no less than one of these three
  functions.*/
  Core.prototype.grandPublicAccessTo = function(instance) {
    instance.public_data1 = mCore.public_data1;
    instance.public_data2 = mCore.public_data2;
    instance.public_function1 = function() { mCore.public_function1(); }
    instance.public_function2 = function() { mCore.public_function2(); }
  }
  Core.prototype.grandProtectedAccessTo = function(instance) {
    this.grandPublicAccessTo(instance);
    instance.protected_data1 = mCore.protected_data1;
    instance.protected_data2 = mCore.protected_data2;
    instance.protected_function1 = function() { mCore.protected_function1(); }
    instance.protected_function2 = function() { mCore.protected_function2(); }
  }
  Core.prototype.grandPrivateAccessTo = function(instance) {
    this.grandProtectedAccessTo(instance);
    instance.private_data1 = mCore.private_data1;
    instance.private_data2 = mCore.private_data2;
    instance.private_function1 = function() { mCore.private_function1(); }
    instance.private_function2 = function() { mCore.private_function2(); }
  }
  /*--------------------------------------------------------------------------*/
  var mCore = new Core();

  this.inherit = function(heir, core) {
    /*Grand the base core access to every member of heir's core, and ... */
    core.grandPrivateAccessTo(mCore);
    /*... grand the heir's core access to public and protected members of the
    base's core.*/
    mCore.grandProtectedAccessTo(heir);
  }

  /*Grand public access to every instance of Base.*/
  mCore.grandPublicAccessTo(this);
};

function Child() {
  'use strict';
  /*--------------------------------------------------------------------------*/
  /*Declare a few data members to demonstrate that these mask the corresponding
  members of Base.*/
  function Core() {
    this.private_data2 = 'private data2 of Child';
    this.protected_data2 = 'protected data2 of Child';
    this.public_data2 = 'public data2 of Child';
  }
  /*Overload some member functions to demonstrate that too.*/
  Core.prototype.private_function2 = function() {
    console.log('private function2 of Child.');
  };
  Core.prototype.protected_function2 = function() {
    console.log('protected function2 of Child.');
  };
  Core.prototype.public_function2 = function() {
    console.log('public function2 of Child.');
  };
  /*--------------------------------------------------------------------------*/
  /*Define visibility of the members. If you're editing the core, make sure that
  each member is listed in no more and no less than one of these three
  functions.*/
  Core.prototype.grandPublicAccessTo = function(instance) {
    instance.public_data2 = mCore.public_data2;
    instance.public_function2 = function() { mCore.public_function2(); }
  }
  Core.prototype.grandProtectedAccessTo = function(instance) {
    this.grandPublicAccessTo(instance);
    instance.protected_data2 = mCore.protected_data2;
    instance.protected_function2 = function() { mCore.protected_function2(); }
  }
  Core.prototype.grandPrivateAccessTo = function(instance) {
    this.grandProtectedAccessTo(instance);
    instance.private_data2 = mCore.private_data2;
    instance.private_function2 = function() { mCore.private_function2(); }
  }
  /*--------------------------------------------------------------------------*/
  var mCore = new Core();

  /*Inherit from Base. Multiple inheritance is possible.*/
  var base = new Base();
  base.inherit(this, mCore);

  /*Grand public access to every instance of Child.*/
  mCore.grandPublicAccessTo(this);
};

function main() {
  'use strict';

  console.log('testing base');
  var base = new Base();
  base.public_function1();
  /*Thinks like this:
  base.private_function1();
  would result in a TypeError.*/

  console.log('testing child');
  var child = new Child();
  child.public_function1();
}
main();                                                    
输出:
测试基地
基地的公共功能1。
受保护的基本功能1。
基地的专用功能1。
基础的公共数据1
基本的受保护数据1
基地的私有数据1
基地的公共功能2。
受保护的基本功能2。
基地的专用功能2。
基础的公共数据2
基本的受保护数据2
基地的私有数据2
测试儿童
基地的公共功能1。
受保护的基本功能1。
基地的专用功能1。
基础的公共数据1
基本的受保护数据1
基地的私有数据1
儿童的公共职能2。
受保护的儿童功能2。
儿童的私人功能2。
子项的公共数据2
子级的受保护数据2

Child的私有数据2

我认为这是不可能的。Javascript没有访问修饰符的概念。所以不,不可能已经answered@user1515084这个答案使用的是范围变量,IMHO不是任何类型的成员。你说它们不是任何类型的成员是什么意思?
prototype
的每个属性都可以通过子类的任何实例公开访问。我们不能用
prototype
属性来实现这一点。关于
Base
inherit
方法,为什么要让基类的core
private
访问派生类的core,基类不应该不知道从它派生的类吗?您的解决方案看起来很干净,但同样,我们只处理实例属性,因此不使用基于
prototype
的继承。你能告诉我在每堂课中引入
核心
的动机吗?我的意思是,首先,每个类都可以让每个
public
成员直接公开,并让每个其他成员作为私有变量
private
protected
。此外,每个类都可以公开一个方法,该方法允许其他类将该类的
受保护的
成员公开给它们。@Bharat Khatri:基类使用派生类的核心使派生类能够重载基类的方法。如果没有这一点,最后6行输出将有所不同。@Bharat KhatriL:我是用这样的愿景来实现的:核心拥有一切;它周围的物体只不过是一种防御机制。我想改进核心继承并标准化围栏,以便所有类对象共享相同的围栏。