javascript - 仍然对 js Prototype 感到困惑

标签 javascript prototype

我对原型(prototype)的实际用途感到困惑。我现在正在学习 HTML canvas,对于其中一个示例,它使用原型(prototype)来声明绘制方法。但是使用原型(prototype)与简单地将其放入构造函数本身有什么区别?

这个例子不是书上的吗:

function Ball (radius, color) {
    if (radius === undefined) { radius = 40; }
    if (color === undefined) { color = "#ff0000"; }
    this.x = 0;
    this.y = 0;
    this.radius = radius;
    this.rotation = 0;
    this.scaleX = 1;
    this.scaleY = 1;
    this.color = utils.parseColor(color);
    this.lineWidth = 1;
    }


Ball.prototype.draw = function (context) {
context.save();
context.translate(this.x, this.y);
context.rotate(this.rotation);
context.scale(this.scaleX, this.scaleY);
context.lineWidth = this.lineWidth;
context.fillStyle = this.color;
context.beginPath();
//x, y, radius, start_angle, end_angle, anti-clockwise
context.arc(0, 0, this.radius, 0, (Math.PI * 2), true);
context.closePath();
context.fill();
if (this.lineWidth > 0) {
context.stroke();
}
context.restore();
};

与放入此内容相同?:

function Ball(radius, color){
...
this.draw = function (context) {
    context.save();
    context.translate(this.x, this.y);
    context.rotate(this.rotation);
    context.scale(this.scaleX, this.scaleY);
    context.lineWidth = this.lineWidth;
    context.fillStyle = this.color;
    context.beginPath();
    //x, y, radius, start_angle, end_angle, anti-clockwise
    context.arc(0, 0, this.radius, 0, (Math.PI * 2), true);
    context.closePath();
    context.fill();
    if (this.lineWidth > 0) {
    context.stroke();
    }
    context.restore();
    };
}

最佳答案

prototype 是一个由所有其他将其作为 prototype 的对象共享的对象,这导致动态添加到 prototype 的方法可以由所有实例共享。

function ClassA(){
    this.sayHello = function(){
        return "hello!";
    }
}

var instanceA = new ClassA();
instanceA.sayHello();//return "hello!";
//add a method to instanceA
instanceA.sayBye = function(){ return "Bye!"; }

var instanceB = new ClassA();
instanceB.sayBye(); //error, sayBye is not a method of instanceB.

//But, this really works
ClassA.prototype.sayBye = function(){ return "Bye!"; }

并且,由于所有实例共享单个原型(prototype),因此所有方法仅保留在内存中的一个位置。在您的第二个实现中,每个实例都有自己的方法,这导致使用大量内存。

将方法排除在 Class 的定义之外可以使代码更加简洁和可读,尽管这不是一个强有力的证据。

有了原型(prototype),开发人员可以更轻松地以 OOP 风格编写代码。

 function ClassB(){
 }
 ClassB.prototype = new ClassA();
 // The equivalent approach may be this
 function ClassB(){
     ClassA.apply(this);
 }

这两种方法都可以完成相同的工作,因此请选择您喜欢的任何一种。

关于javascript - 仍然对 js Prototype 感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11823545/

相关文章:

javascript - 原型(prototype) addMethods 返回 "undefined"

javascript - 如何从 javascript 模块模式中的函数原型(prototype)访问私有(private)属性?

javascript - Ajax JSON SUMIF 数组包含特定单词

javascript - 如何动态渲染组件列表而不用每次添加新组件都重新渲染整个列表?

javascript - Bokeh 从 CustomJS 获取值(更改数据源中的值)

javascript - 代码 ReplaceWith 中的 JQuery 函数错误

javascript - 如何从对象函数javascript返回多个值?

javascript - 如何创建一个具有许多其他对象功能别名的对象

javascript - 如果原型(prototype)无法访问私有(private)变量,那么 "clean up"代码的最佳方法是什么?

javascript - 从 React 中的 CORS API 调用中得到 undefined