javascript - 使用原型(prototype)与直接在构造函数中定义方法相比有何优点?

标签 javascript oop prototype

我想知道使用其中任何一个相对于其他是否有任何优势,我应该走哪条路?

构造方法:

var Class = function () {

    this.calc = function (a, b) {
        return a + b;
    };

};

原型(prototype)方法:

var Class = function () {};

Class.prototype.calc = function (a, b) {
    return a + b;
};

我不喜欢这样,使用原型(prototype),方法定义与类分离,我不知道是否有任何具体原因我应该使用它而不是第一种方法。

此外,与函数定义相比,使用函数文字来定义“类”是否有任何好处:

var Class = function () {};

对比

function Class () {};

谢谢!

最佳答案

通过原型(prototype)链继承的方法可以针对所有实例进行通用更改,例如:

function Class () {}
Class.prototype.calc = function (a, b) {
    return a + b;
}

// Create 2 instances:
var ins1 = new Class(),
    ins2 = new Class();

// Test the calc method:
console.log(ins1.calc(1,1), ins2.calc(1,1));
// -> 2, 2

// Change the prototype method
Class.prototype.calc = function () {
    var args = Array.prototype.slice.apply(arguments),
        res = 0, c;

    while (c = args.shift())
        res += c;

    return res; 
}

// Test the calc method:
console.log(ins1.calc(1,1,1), ins2.calc(1,1,1));
// -> 3, 3

请注意如何更改应用于两个实例的方法?这是因为 ins1ins2 共享相同的 calc() 函数。为了使用在构造期间创建的公共(public)方法来执行此操作,您必须将新方法分配给已创建的每个实例,这是一项尴尬的任务。这是因为 ins1ins2 将拥有自己的、单独创建的 calc() 函数。

在构造函数内创建方法的另一个副作用是性能较差。每次构造函数运行时都必须创建每个方法。原型(prototype)链上的方法创建一次,然后由每个实例“继承”。另一方面,公共(public)方法可以访问“私有(private)”变量,而继承方法则无法做到这一点。

对于您的 function Class() {}var Class = function () {} 问题,前者被“提升”到当前作用域的顶部执行前。对于后者,变量声明被提升,但赋值不被提升。例如:

// Error, fn is called before the function is assigned!
fn();
var fn = function () { alert("test!"); } 

// Works as expected: the fn2 declaration is hoisted above the call
fn2();
function fn2() { alert("test!"); }

关于javascript - 使用原型(prototype)与直接在构造函数中定义方法相比有何优点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33753034/

相关文章:

javascript - 如何使用javascript在头像上创建下拉菜单?

javascript - 如何获取 html.erb 文件中的 JavaScript 以在 Rails 4 应用程序中呈现?

javascript - 多条件数组动态过滤

python - 在类内访问 `__attr` 时,名称修改如何工作?

javascript - 了解基本原型(prototype)设计和更新键/值对

javascript - 如何使用javascript获取超链接的文本

Python 相当于 Java 的 compareTo()

c - 当一个对象需要修改另一个对象时的 OOP 最佳实践

javascript - 如何通过观察其他 <div> 容器中的鼠标悬停来隐藏一个 <div> 内的一个元素

javascript - 使用可变数量的参数调用类对象