在构造函数与原型中声明javascript对象方法 [英] Declaring javascript object method in constructor function vs. in prototype

查看:83
本文介绍了在构造函数与原型中声明javascript对象方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在创建 javascript 对象时,我可以在构造函数或原型中放置方法声明.例如,假设我想要一个具有 Name 属性和 Bark 方法的 Dog 类.我可以将 Bark 方法的声明放入构造函数中:

In creating javascript objects, I can put a method declaration either in the constructor function or in the prototype. For example, say I want a Dog class that has a Name property and a Bark method. I can put the declaration of the Bark method into the constructor function:

var Dog = function(name) {
    this.Name = name;
    this.Bark = function() {
        alert(this.Name + " bark");
    };
}

或者我可以把它作为一个方法放在原型对象上:

or I could put in as a method on the prototype object:

var Dog = function(name) {
    this.Name = name;
}

Dog.prototype.Bark = function() {
    alert(this.Name + " bark");
};

当我实例化 Dog 类型的对象时,两种方法似乎都可以正常工作:

When I instantiate objects of type Dog, both approaches seem to work fine:

var dog = new Dog("Fido");
dog.Bark();  //Both approaches show "Fido bark"

我应该更喜欢这些方法中的一种吗?使用一个比另一个有什么优势吗?在幕后,这两种方法最终会做完全相同的事情吗?大多数人倾向于哪种方法?

Should I prefer one of these approaches over the other? Are there any advantages to using one over the other? Behind the scenes, do these two approaches end up doing exactly the same thing? Which approach do most people tend to favor?

感谢您的帮助.

推荐答案

对于你给出的例子,你应该使用原型方法.一般来说,这取决于.第一种方法(在构造函数中初始化方法)的主要优点是您可以通过在方法中使用构造函数中定义的局部变量来利用闭包.这些变量不能在构造函数之外直接访问,因此实际上是私有的",这意味着您的 API 比将这些变量定义为对象的属性时更简洁.一些一般经验法则:

For the example you give, you should use the prototype approach. In general, it depends. The main advantage of the first approach (initializing methods in the constructor) is that you can take advantage of closures by making use of local variables defined within the constructor in your methods. These variables are not directly accessible outside the constructor function so are effectively "private", meaning your API is cleaner than if these variable were instead defined as properties of the object. Some general rules of thumb:

  • 如果您的方法不使用在构造函数中定义的局部变量(您的示例没有),则使用原型方法.
  • 如果您要创建大量 Dog,请使用原型方法.这样,所有实例"(即由 Dog 构造函数创建的对象)将共享一组函数,而构造函数的方式,每次 Dog<都会创建一组新函数/code> 构造函数被调用,使用更多内存.
  • 如果您正在创建少量 Dog 并发现在构造函数中使用本地私有"变量可以改进您的代码,那么这可能是更好的方法.如果性能或内存消耗是主要问题,请使用您的判断并进行一些基准测试.
  • If your methods do not use local variables defined in your constructor (your example doesn't), then use the prototype approach.
  • If you're creating lots of Dogs, use the prototype approach. This way, all "instances" (i.e. objects created by the Dog constructor) will share one set of functions, whereas the constructor way, a new set of functions is created every time the Dog constructor is called, using more memory.
  • If you're creating a small number of Dogs and find that using local, "private" variables in your constructor improves your code, this may be the better approach. Use your judgment and do some benchmarks if performance or memory consumption are major concerns.

可以使用混合方法,即只在构造函数中定义需要访问本地私有构造函数变量的方法,而将其他方法分配给原型.

It is possible to use a hybrid approach whereby only methods that need access to local private constructor variables are defined in the constructor while other methods are assigned to the prototype.

例如,下面的代码在构造函数中使用了一个局部变量来跟踪这只狗吠叫的次数,同时将实际数量保密,因此在构造函数中定义了与吠叫相关的方法.摇尾不需要访问吠叫的次数,因此可以在原型上定义该方法.

For example, the code below uses a local variable in the constructor to keep track of the number of times this dog has barked while keeping the actual number private, so the barking-related methods are defined inside the constructor. Tail wagging does not require access to the number of barks, therefore that method can be defined on the prototype.

var Dog = function(name) {
    this.name = name;

    var barkCount = 0;

    this.bark = function() {
        barkCount++;
        alert(this.name + " bark");
    };

    this.getBarkCount = function() {
        alert(this.name + " has barked " + barkCount + " times");
    };
};

Dog.prototype.wagTail = function() {
    alert(this.name + " wagging tail");
};

var dog = new Dog("Dave");
dog.bark();
dog.bark();
dog.getBarkCount();
dog.wagTail();

这篇关于在构造函数与原型中声明javascript对象方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆