javascript - JavaScript .prototype 如何工作?

标签 javascript dynamic-languages prototype-oriented

我不太喜欢动态编程语言,但我已经编写了相当多的 JavaScript 代码。我从来没有真正理解过这种基于原型(prototype)的编程,有人知道它是如何工作的吗?

var obj = new Object();
obj.prototype.test = function() { alert('Hello?'); };
var obj2 = new obj();
obj2.test();

我记得不久前我与人们进行了很多讨论(我不太确定我在做什么),但据我了解,没有类的概念。它只是一个对象,这些对象的实例是原始对象的克隆,对吗?

但是 JavaScript 中这个“.prototype”属性的确切用途是什么?它与实例化对象有何关系?

更新:正确的方法

var obj = new Object(); // not a functional object
obj.prototype.test = function() { alert('Hello?'); }; // this is wrong!

function MyObject() {} // a first class functional object
MyObject.prototype.test = function() { alert('OK'); } // OK

还有这些slides真的帮了很多忙。

最佳答案

在 Java、C# 或 C++ 等实现经典继承的语言中,您首先创建一个类(对象的蓝图),然后您可以从该类创建新对象,也可以扩展该类,定义一个新的对象。增强原始类的类。

在 JavaScript 中,您首先创建一个对象(没有类的概念),然后您可以扩充自己的对象或从中创建新对象。这并不难,但是对于习惯了古典方式的人来说有点陌生并且难以代谢。

示例:

//Define a functional object to hold persons in JavaScript
var Person = function(name) {
  this.name = name;
};

//Add dynamically to the already defined object a new getter
Person.prototype.getName = function() {
  return this.name;
};

//Create a new object of type Person
var john = new Person("John");

//Try the getter
alert(john.getName());

//If now I modify person, also John gets the updates
Person.prototype.sayMyName = function() {
  alert('Hello, my name is ' + this.getName());
};

//Call the new method on john
john.sayMyName();

到目前为止,我一直在扩展基础对象,现在我创建另一个对象,然后从 Person 继承。

//Create a new object of type Customer by defining its constructor. It's not 
//related to Person for now.
var Customer = function(name) {
    this.name = name;
};

//Now I link the objects and to do so, we link the prototype of Customer to 
//a new instance of Person. The prototype is the base that will be used to 
//construct all new instances and also, will modify dynamically all already 
//constructed objects because in JavaScript objects retain a pointer to the 
//prototype
Customer.prototype = new Person();     

//Now I can call the methods of Person on the Customer, let's try, first 
//I need to create a Customer.
var myCustomer = new Customer('Dream Inc.');
myCustomer.sayMyName();

//If I add new methods to Person, they will be added to Customer, but if I
//add new methods to Customer they won't be added to Person. Example:
Customer.prototype.setAmountDue = function(amountDue) {
    this.amountDue = amountDue;
};
Customer.prototype.getAmountDue = function() {
    return this.amountDue;
};

//Let's try:       
myCustomer.setAmountDue(2000);
alert(myCustomer.getAmountDue());

var Person = function (name) {
    this.name = name;
};
Person.prototype.getName = function () {
    return this.name;
};
var john = new Person("John");
alert(john.getName());
Person.prototype.sayMyName = function () {
    alert('Hello, my name is ' + this.getName());
};
john.sayMyName();
var Customer = function (name) {
    this.name = name;
};
Customer.prototype = new Person();

var myCustomer = new Customer('Dream Inc.');
myCustomer.sayMyName();
Customer.prototype.setAmountDue = function (amountDue) {
    this.amountDue = amountDue;
};
Customer.prototype.getAmountDue = function () {
    return this.amountDue;
};
myCustomer.setAmountDue(2000);
alert(myCustomer.getAmountDue());

虽然如上所述,我无法对 Person 调用 setAmountDue()、getAmountDue()。

//The following statement generates an error.
john.setAmountDue(1000);

关于javascript - JavaScript .prototype 如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45833167/

相关文章:

java - 在servlet上上传 Canvas base64图像

.net - 有人用过 Boo 吗?你能评论一下你的经历吗?

Javascript 扩展原型(prototype)和 for-in

javascript - 值得使用原型(prototype)还是我们应该为 javascript 使用 OOP?

dependency-injection - 动态语言中是否需要依赖注入(inject)?

javascript - 这些代码有什么区别?

javascript - Requirejs - 通过不同的模块共享相同的依赖

javascript - 无法获得下拉 3 栏菜单以具有背景或关闭

javascript 如何解析数字?

dynamic-languages - 为什么动态语言的 “Dynamic”部分如此好?