据说Javascript的一个主要优点是它是一种基于原型的语言.
但是,Javascript基于原型是什么意思,为什么这是一个优势呢?
在JavaScript中,每个对象都是实例和类.要进行继承,可以使用任何对象实例作为原型.
在Python,C++等中,有类和实例作为单独的概念.为了进行继承,您必须使用基类来创建一个新类,然后可以使用它来生成派生实例.
为什么JavaScript会朝这个方向发展(基于原型的面向对象)?基于原型的OO相对于传统的,基于类的OO有哪些优点(和缺点)?
我是JavaScript OOP的新手.你能解释下面的代码块之间的区别吗?我测试了两个块都有效.什么是最佳实践,为什么?
第一块:
function Car(name){
this.Name = name;
}
Car.prototype.Drive = function(){
console.log("My name is " + this.Name + " and I'm driving.");
}
SuperCar.prototype = new Car();
SuperCar.prototype.constructor = SuperCar;
function SuperCar(name){
Car.call(this, name);
}
SuperCar.prototype.Fly = function(){
console.log("My name is " + this.Name + " and I'm flying!");
}
var myCar = new Car("Car");
myCar.Drive();
var mySuperCar = new SuperCar("SuperCar");
mySuperCar.Drive();
mySuperCar.Fly();Run Code Online (Sandbox Code Playgroud)
第二块:
function Car(name){
this.Name = name;
this.Drive = function(){
console.log("My name is " + this.Name + …Run Code Online (Sandbox Code Playgroud)javascript oop inheritance constructor prototype-programming
我搜索了这么多链接,并且不能很好地了解经典继承和原型继承之间的区别?
我从中学到了一些东西,但我仍然对这些概念感到困惑.
经典继承
// Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
}
//superclass method
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info("Shape moved.");
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); //call super constructor.
}
//subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Run Code Online (Sandbox Code Playgroud)
经典继承是否在内部使用原型继承?
http://aaditmshah.github.io/why-prototypal-inheritance-matters/
从上面的链接,我了解到我们不能在运行时在经典继承中添加新方法.它是否正确?但是你可以查看上面的代码我可以在运行时通过原型添加"move"方法和任何方法.那么这是基于原型的经典继承吗?如果是这样,什么是实际的经典继承和原型继承?我很困惑.
原型继承.
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.area = function () {
var radius = this.radius;
return Math.PI * …Run Code Online (Sandbox Code Playgroud) 原型系统看起来比传统的类系统更灵活,但人们似乎对所谓的"最佳实践"感到满意,它模仿了传统的类系统:
function foo() {
// define instance properties here
}
foo.prototype.method = //define instance method here
new foo()
Run Code Online (Sandbox Code Playgroud)
原型系统必须具备其他所有灵活性.
在模仿课程之外是否有用于原型系统的用途?什么样的东西原型可以做哪些类不能,或者没有?
我想知道 - JavaScript对象,类和函数之间有什么区别?我是否正确地认为类和函数是对象的类型?
什么能够将一个类与一个函数区分开来?或者它们真的是一样的,只是它们的用语根据它们的使用方式而变化?
function func() { alert('foo'); } // a function
func(); // call the function - alerts 'foo'
var func2 = function () { alert('hello'); } // acts the same way as 'func' surely?
func2(); // alerts 'hello'
var Class = function() { alert('bar'); }; // a class
var c = new Class(); // an istance of a class - alerts 'bar'
Run Code Online (Sandbox Code Playgroud)
当然,类有方法和属性,可以实例化 - 但是,我可以对任何旧函数做同样的事情 - 或者不是吗?
为什么基于类的OO如此受欢迎而不是基于原型的OO?他们是否在学校教授后者?虽然Javascript是基于原型的,但大多数人主要使用它,或者通过试图模拟基于类的系统的框架.
我知道Sun已经对Self进行了一些研究- 是否有关于原型oo的其他任何知识来源?最好是可以自学的东西.
我找到了一本包含已发表论文的书:基于原型的编程:概念,语言和应用
有人读过吗?
-
所以我给了我最大的回答.不过,我真的不太满意.我本来希望听到更多技术性的答案.也许我没有很好地解释自己.
基于javascript原型的面向对象编程风格很有趣,但是在很多情况下你需要能够从类创建对象.
例如,在矢量绘图应用程序中,工作空间通常在绘图开始时为空:我无法从现有工作空间创建新的"行".更一般地说,动态创建对象的每种情况都需要使用类.
我已经阅读了很多教程和书"Javascript:好的部分",但在我看来,没有办法定义尊重1)封装的类和2)有效的成员方法声明(我的意思是:成员)正在定义的方法,并在每个类实例之间共享).
要定义私有变量,正在使用闭包:
function ClassA()
{
var value = 1;
this.getValue = function()
{
return value;
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是"ClassA"的每个实例都有自己的成员函数"getValue"的副本,这是无效的.
要有效地定义成员函数,正在使用原型:
function ClassB()
{
this.value = 1;
}
ClassB.prototype.getValue = function()
{
return this.value;
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是成员变量"value"是公共的.
我不认为这个问题可以轻易解决,因为在创建对象期间需要定义"私有"变量(以便对象可以访问其创建的上下文,而不暴露those值)而基于原型的成员函数定义必须在对象创建后完成,因此原型有意义("this.prototype"不存在,我已经检查过).
或者我错过了什么?
编辑:
首先,感谢您的有趣答案.
我只想为我的初始消息添加一点精度:
我真正想做的是拥有1)私有变量(封装是好的,因为人们只能访问他们需要的东西)和2)有效的成员方法声明(避免拷贝).
似乎简单的私有变量声明只能通过javascript中的闭包来实现,这就是为什么我专注于基于类的方法.如果有一种方法可以用基于原型的方法实现简单的私有变量声明,那对我来说没问题,我不是一个激烈的基于类的方法proponnent.
在阅读答案后,似乎简单的解决方案是忘记私有,并使用特殊的编码约定来阻止其他程序员直接访问"私有"变量...
我同意,我的标题/第一句话对于我想在这里讨论的问题有误导性.
我已经读过Crockford推动以更明显的原型方式使用JavaScript(克隆对象来创建新的,从不使用"new"关键字).但在野外,我从未见过任何人将这种风格用于大型项目.
我在哪里可以找到使用此样式的大型项目的示例?
javascript ×10
oop ×8
inheritance ×4
class ×3
constructor ×1
private ×1
prototype ×1
selflanguage ×1