我不太喜欢动态编程语言,但我已经编写了相当多的JavaScript代码。我从未真正了解过这种基于原型的编程,有人知道它是如何工作的吗?
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
这些幻灯片也帮了大忙。
看完这篇文章后,我对JavaScript原型链感到困惑,然后我找到了这些图表
http://iwiki.readthedocs.org/en/latest/javascript/js_core.html#inheritance
这是一个清晰的图表,通过原型链显示JavaScript继承
and
http://www.javascriptbank.com/javascript/article/JavaScript_Classical_Inheritance/
这一个包含一个带有代码的示例和几个漂亮的图表。
原型链最终返回到Object.prototype。原型链可以根据您的需要进行技术上的扩展,每次都将子类的原型设置为父类的对象。
希望这对您理解JavaScript原型链也有帮助。
在Java、C#或C++等实现经典继承的语言中,首先要创建一个类——一个对象的蓝图——然后可以从该类创建新对象,或者可以扩展该类,定义一个新类来扩充原始类。
在JavaScript中,您首先创建一个对象(没有类的概念),然后您可以扩充自己的对象或从中创建新对象。这并不难,但对于习惯了传统方式的人来说,有点陌生,很难消化。
例子:
//在JavaScript中定义一个函数对象以容纳人员var Person=函数(名称){this.name=名称;};//向已定义的对象动态添加一个新的getterPerson.prototype.getName=函数(){返回this.name;};//创建Person类型的新对象var john=新人(“john”);//试试吸气剂警报(john.getName());//如果现在我修改人,John也会得到更新Person.prototype.sayMyName=函数(){alert('你好,我的名字是'+this.getName());};//对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=函数(名称){this.name=名称;};Person.prototype.getName=函数(){返回this.name;};var john=新人(“john”);警报(john.getName());Person.prototype.sayMyName=函数(){alert('你好,我的名字是'+this.getName());};john.sayMyName();var客户=函数(名称){this.name=名称;};Customer.prototype=新角色();var myCustomer=新客户(“梦想股份有限公司”);myCustomer.sayMyName();Customer.prototype.setAmountDue=函数(amountDue){this.amountDue=amountDue;};Customer.prototype.getAmountDue=函数(){return this.amountDue;};myCustomer.setAmountDue(2000);警报(myCustomer.getAmountDue());
虽然如上所述,我不能调用setAmountDue(),但对Person调用getAmountDu()。
//The following statement generates an error.
john.setAmountDue(1000);
摘要:
函数是javascript中的对象,因此可以具有财产(构造函数)函数始终具有原型属性当函数用作带有new关键字的构造函数时,对象将获得原型。可以在新创建的对象的__proto__属性中找到对该原型的引用。此__proto__属性引用构造函数的原型属性。
例子:
职能人员(姓名){this.name=名称;}let me=新人('willem');console.log(Person.prototype)//Person具有prototype属性console.log(Person.prototype==me.__proto__)//实例的__proto__属性引用函数的原型属性。
为什么这很有用:
Javascript在查找Objects上的财产时有一种机制,称为“原型继承”,其基本功能如下:
如果属性位于Object本身,则选中First。如果是,则返回此属性。如果属性不位于对象本身,它将“爬上协议链”。它基本上看proto属性所指的对象。在那里,它检查proto引用的对象上的属性是否可用如果属性不位于原型对象上,它将沿着原型链一直爬到对象对象。如果在对象及其原型链上找不到属性,则返回undefined。
例如:
职能人员(姓名){this.name=名称;}let mySelf=新人('Wilem');console.log(mySelf.__proto__==Person.prototype);console.log(mySelf.__proto__.__proto__==对象.原型);
更新:
__proto__属性已被弃用,尽管它在大多数现代浏览器中实现,但获取原型对象引用的更好方法是:
对象.getPrototypeOf()