functionSayHello()//先定义一份SayHello函数代码
{
alert("Hello,I'm"+this.name);
};
functionPerson(name)//带参数的构造函数
{
this.name=name;//将参数值赋给给this对象的属性
this.SayHello=SayHello;//给this对象SayHello方法赋值为前面那份SayHello代码。
};
varBillGates=newPerson("BillGates");//创建BillGates对象
varSteveJobs=newPerson("SteveJobs");//创建SteveJobs对象
alert(BillGates.SayHello==SteveJobs.SayHello);//显示:true
从上面代码可以看出,BillGates和SteveJobs的SayHello是共享以快内存的,dna是Person类和SayHello方法联系不够紧密。
Javascript中的对象都有以个prototype属性,且此属性是个object型的对象。因此我们也可以给这个prototype对象添加任意的属性和方法。既然prototype是对象的“原型”,那么由该函数构造出来的对象应该都会具有这个“原型”的特性。事实上,在构造函数的prototype上定义的所有属性和方法,都是可以通过其构造的对象直接访问和调用的。也可以这么说,prototype提供了一群同类对象共享属性和方法的机制。
用原型模式写出来如下:
function Person(name)
{
this.name = name; //设置对象属性,每个对象各自一份属性数据
};
Person.prototype.SayHello = function() //给Person函数的prototype添加SayHello方法。
{
alert("Hello, I'm " + this.name);
}
var BillGates = new Person("Bill Gates"); //创建BillGates对象
var SteveJobs = new Person("Steve Jobs"); //创建SteveJobs对象
BillGates.SayHello(); //通过BillGates对象直接调用到SayHello方法
SteveJobs.SayHello(); //通过SteveJobs对象直接调用到SayHello方法
alert(BillGates.SayHello == SteveJobs.SayHello); //因为两个对象是共享prototype的SayHello,所以显示:true
再看一下下面的代码,两个对象的sayhello方法不是共享内存的:
function Person(name) //带参数的构造函数
2 {
3 this.name = name; //将参数值赋给给this对象的属性
4 this.SayHello = function() {alert("Hello, I'm " + this.name);}; //给this对象定义一个SayHello方法。
5 };
6
7 function Employee(name, salary) //子构造函数
8 {
9 Person.call(this, name); //将this传给父构造函数
10 this.salary = salary; //设置一个this的salary属性
11 this.ShowMeTheMoney = function() {alert(this.name + " $" + this.salary);}; //添加ShowMeTheMoney方法。
12 };
13
14 var BillGates = new Person("Bill Gates"); //用Person构造函数创建BillGates对象
15 var SteveJobs = new Employee("Steve Jobs", 1234); //用Empolyee构造函数创建SteveJobs对象
16
17 BillGates.SayHello(); //显示:I'm Bill Gates
18 SteveJobs.SayHello(); //显示:I'm Steve Jobs
19 SteveJobs.ShowMeTheMoney(); //显示:Steve Jobs $1234
20
21 alert(BillGates.constructor == Person); //显示:true
22 alert(SteveJobs.constructor == Employee); //显示:true
23
24 alert(BillGates.SayHello == SteveJobs.SayHello); //显示:false
Employee意义上是Person类的子类,它会调用父类的构造方法:Person.call(this),那么我的疑问就是其继承了父类的SayHello方法为什么Sayhello不共享内存呢?
书上说每一个对象的函数体,都在内存中存储着自己的副本,就像java的父类和子类一样,则虽然他们的结构是一样的但是不共享内存。
再看下面的例子:
function Person(name) //基类构造函数
2 {
3 this.name = name;
4 };
5
6 Person.prototype.SayHello = function() //给基类构造函数的prototype添加方法
7 {
8 alert("Hello, I'm " + this.name);
9 };
10
11 function Employee(name, salary) //子类构造函数
12 {
13 Person.call(this, name); //调用基类构造函数
14 this.salary = salary;
15 };
16
17 Employee.prototype = new Person(); //建一个基类的对象作为子类原型的原型,这里很有意思
18
19 Employee.prototype.ShowMeTheMoney = function() //给子类添构造函数的prototype添加方法
20 {
21 alert(this.name + " $" + this.salary);
22 };
23
24 var BillGates = new Person("Bill Gates"); //创建基类Person的BillGates对象
25 var SteveJobs = new Employee("Steve Jobs", 1234); //创建子类Employee的SteveJobs对象
26
27 BillGates.SayHello(); //通过对象直接调用到prototype的方法
28 SteveJobs.SayHello(); //通过子类对象直接调用基类prototype的方法,关注!
29 SteveJobs.ShowMeTheMoney(); //通过子类对象直接调用子类prototype的方法
30
31 alert(BillGates.SayHello == SteveJobs.SayHello); //显示:true,表明prototype的方法是共享的
第17行父类的对象返回给子类的prototype属性,且基类的sayhello方法也声明为prototype,这样父类和子类的sayhello方法就是共享内存的。言外之意,父类和子类对象指针都指向同一片区域。
prototype不但能让对象共享自己财富,而且prototype还有寻根问祖的天性,从而使得先辈们的遗产可以代代相传。当从一个对象那里读取属性或调用方法时,如果该对象自身不存在这样的属性或方法,就会去自己关联的prototype对象那里寻找;如果prototype没有,又会去prototype自己关联的前辈prototype那里寻找,直到找到或追溯过程结束为止。
在JavaScript内部,对象的属性和方法追溯机制是通过所谓的prototype链来实现的。当用new操作符构造对象时,也会同时将构造函数的prototype对象指派给新创建的对象,成为该对象内置的原型对象。对象内置的原型对象应该是对外不可见的,尽管有些浏览器(如Firefox)可以让我们访问这个内置原型对象,但并不建议这样做。内置的原型对象本身也是对象,也有自己关联的原型对象,这样就形成了所谓的原型链。
在原型链的最末端,就是Object构造函数prototype属性指向的那一个原型对象。这个原型对象是所有对象的最老祖先,这个老祖宗实现了诸如toString等所有对象天生就该具有的方法。其他内置构造函数,如Function, Boolean, String, Date和RegExp等的prototype都是从这个老祖宗传承下来的,但他们各自又定义了自身的属性和方法,从而他们的子孙就表现出各自宗族的那些特征。
这就是“继承”,是JavaScript特有的“原型继承”。
分享到:
相关推荐
深入理解javascript原型和闭包(01)——一切都是对象 深入理解javascript原型和闭包(02)——函数和对象的关系
浅析Javascript原型继承,浅析Javascript原型继承
JavaSciptDOM基本操作,JavaScipt函数基础,JavaScipt流程语句,JavaScript变量,JavaScript数据类型,JavaScript数组,JavaScript正则表达式,JavaScript字符串函数,Window对象等图解。JS高手进阶的工具图谱
javascript原型和闭包
浅析javascript原型继承机制,浅析javascript原型继承机制
理解Javascript原型继承原理
探究JavaScript原型数据共享与方法共享实现 数据共享 需要共享的数据就可以写原型中 原型的作用之一:数据共享 属性需要共享,方法也需要共享: 不需要共享的数据写在构造函数中 需要共享的数据写在原型中 ...
javascript原型继承,prototype的使用,可以像java一样继承
【技术分享】从浅入深 Javascript 原型链与原型链污染 APT web安全 网络安全 安全 自动化
Toast.js:一个JavaScript原型吐司消息Toast messages
javascript原型继承机制参考.pdf
javascript原型继承机制借鉴.pdf
javascript原型继承机制归类.pdf
Javascript原型继承Javascript原型继承Javascript原型继承
NULL 博文链接:https://ywxowen999.iteye.com/blog/1135884
基于Javascript原型的Zepto框架设计.pdf
本文实例分析了Javascript原型链的原理。分享给大家供大家参考,具体如下: 一、JavaScript原型链 ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一...
javascript原型继承机制[整理].pdf
在咱们的第一节(深入理解javascript原型和闭包(1)——一切都是对象)中说道,函数也是一种对象。他也是属性的集合,你也可以对函数进行自定义属性。不用等咱