在Javascript中使用原型

As mentioned in my previous post, I think using prototypes is powerful enough to deserve a more detailed explanation. To start off, let me say we are talking about the prototype method here, not the JavaScript library.

正如我之前的文章中提到 ,我认为使用原型足够强大,值得进行更详细的说明。 首先,让我说我们在这里谈论的是原型方法,而不是JavaScript库。

Prototypes allow you to easily define methods to all instances of a particular object. The beauty is that the method is applied to the prototype, so it is only stored in the memory once, but every instance of the object has access to it. Let’s use the Pet object that we created in the previous post. In case you don’t remember it or didn’t read the article (please do) here is the object again:

原型使您可以轻松地为特定对象的所有实例定义方法。 优点是该方法应用于原型,因此它仅在内存中存储一​​次,但是对象的每个实例都可以访问它。 让我们使用在上一篇文章中创建的Pet对象。 如果您不记得它或没有阅读该文章(请记住),这里再次是该对象:

function Pet(name, species){
    this.name = name;
    this.species = species;
}
function view(){
    return this.name + " is a " + this.species + "!";
}
Pet.prototype.view = view;
var pet1 = new Pet('Gabriella', 'Dog');
alert(pet1.view()); //Outputs "Gabriella is a Dog!"

As you can see, by using simply using prototype when we attached the view method, we have ensured that all Pet objects have access to the view method. You can use the prototype method to create much more robust effects. For example, let’s say we want to have a Dog object. The Dog object should inherit each of the methods and properties utilized in the Pet object and we also want a special function that only our Dog objects have access to. Prototype makes this possible.

如您所见,通过在附加view方法时仅使用原型,我们确保了所有Pet对象都可以访问该view方法。 您可以使用原型方法创建更强大的效果。 例如,假设我们要拥有一个Dog对象。 Dog对象应该继承Pet对象中使用的每种方法和属性,并且我们还需要一个特殊的功能,只有我们的Dog对象可以访问。 原型使这成为可能。

function Pet(name, species){
    this.name = name;
    this.species = species;
}
function view(){
    return this.name + " is a " + this.species + "!";
}
Pet.prototype.view = view;
function Dog(name){
    Pet.call(this, name, "dog");
}
Dog.prototype = new Pet();
Dog.prototype.bark = function(){
    alert("Woof!");
}

We set up the Dog object, and have it call the Pet function using the call() method. The call method allows us to call a specific target function within an object by passing in the object we want to run the function on (referenced by ‘this’ on line 10) followed by the arguments. Theoretically, we don’t need to do this. We could just create a ‘name’ and ‘species’ property inside of the Dog object instead of calling the Pet function. Our Dog object would still inherit from the Pet object because of line 12. However that would be a little redundant. Why recreate these properties when we already have access to identical properties inside of the Pet object?

我们设置了Dog对象,并使用call()方法让它调用Pet函数。 调用方法允许我们通过传入要在其上运行函数的对象(在第10行上由“ this”引用)后跟参数来调用对象中的特定目标函数。 从理论上讲,我们不需要这样做。 我们可以在Dog对象内部创建一个“ name”和“ species”属性,而不用调用Pet函数。 由于第12行,我们的Dog对象仍将继承自Pet对象。但这有点多余。 当我们已经可以访问Pet对象内部的相同属性时,为什么还要重新创建这些属性?

Moving on, we then give Dog a custom method called bark that only Dog objects have access to. Keeping this in mind consider the following:

接下来,我们为Dog提供一个名为bark的自定义方法,只有Dog对象才能访问它。 请记住以下几点:

var pet1 = new Pet('Trudy', 'Bird');
var pet2 = new Dog('Gabriella');
alert(pet2.view()); // Outputs "Gabriella is a Dog!"
pet2.bark(); // Outputs "Woof!"
pet1.bark(); // Error

As you can see, the Dog object has inherited the view method from the Pet object, and it has a custom bark method that only Dog objects have access to. Since pet1 is just a Pet, not a Dog, it doesn’t have a bark method and when we try to call it we get an error.

如您所见,Dog对象继承了Pet对象的view方法,并且具有仅Dog对象有权访问的自定义树皮方法。 由于pet1只是宠物,而不是狗,因此它没有树皮方法,当我们尝试调用它时会出现错误。

It is important to understand that prototype follows a chain. When we called pet2.view(), it first checked the Dog object (since that is the type of object pet2 is) to see if the Dog object has a view method. In this case it doesn’t, so it moves up a step. Dog inherits from Pet, so it next checks to see if the Pet object has a view method. It does, so that is what runs. The bottom most layer of inheritance is actually from the Object.prototype itself. Every object inherits from that. So, in theory we could do this:

重要的是要了解原型遵循一条链。 当我们调用pet2.view()时,它首先检查Dog对象(因为pet2是对象的类型),以查看Dog对象是否具有view方法。 在这种情况下,它不是,所以它向上移动了一步。 Dog继承自Pet,因此接下来检查Pet对象是否具有view方法。 确实如此,这就是运行的结果。 继承的最底层实际上是来自Object.prototype本身。 每个对象都从那里继承。 因此,理论上我们可以这样做:

Object.prototype.whoAmI = function(){
    alert("I am an object!");
}
pet1.whoAmI(); //Outputs 'I am an object!'
pet2.whoAmI(); //Outputs 'I am an object!'

Since all objects inherit from the Object.prototype, pet1 and pet2 both can run the whoAmI method. In short, prototype is an immensely powerful tool you can use in your coding. Once you understand how prototype inherits, and the chain of objects it inherits from, you can start to create some really advanced and powerful object combinations. Use the code examples used in this post to play around with and see the different ways you can use prototype to create more robust objects. With something like this, hands-on is definitely the best approach (at least I think so!).

由于所有对象都继承自Object.prototype,因此pet1和pet2都可以运行whoAmI方法。 简而言之,原型是可以在编码中使用的功能非常强大的工具。 一旦了解了原型是如何继承的,以及它所继承的对象链,就可以开始创建一些真正高级且功能强大的对象组合。 使用本文中使用的代码示例进行实验,并了解使用原型创建更强大的对象的不同方法。 通过这种方式,动手操作绝对是最好的方法(至少我认为是这样!)。

翻译自: https://timkadlec.com/2008/01/using-prototypes-in-javascript/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值