JS里的对象在Ajax发展之后, 就跟着疯狂起来, 要玩好JS的对象, 就要搞清楚构造器(constructor), 指针(pointer), 原型(prototype)
这篇文章主要记录我对prototype的理解
prototype
最初的用法是, 为了避免方法在构造器里随机数据被实例化时而产生重复的副本
后来被用在"继承"上面了, 注意, JS语义上是没有继承的, 这里说的是人为的实现
总结, prototype其实也是指针, 默认是实例的指针, 当然也可以人为的改变,
父类A, 子类B
默认情况, B.prototype=A.prototype
这样, B可以访问A的所有原型方法, 这时, B的构造器也变成A了
改变一下, B.prototype=A
这样, B可以访问A的所有静态方法, 这时, B的构造器也变成类A的指针->类的指针->Function的指针->Function的构造器
以下是实例验证
function demo(){
var A=function(name){
this.name=name;
}
A.prototype.showName=function(){alert(this.name);}
var B=function(name, age){
A.call(this, name);
this.age=age;
}
//B.prototype=new A(); //这里2行代码的效果是一样的
B.prototype=A.prototype; //目的是返回A的"实例"的指针
B.prototype.showAge=function(){alert(this.age);}
var b=new B("david", 31);
b.showName();
b.showAge();
}
严重注意以上代码的备注, 是new之后的instance的指针, 不是Class的指针,
下面改一下代码验证一下
var A=function(name){
this.name=name;
//return this; 这是隐式代码, JS会自动帮我们执行, 这里是关键
}
改为
var A=function(name){
var o=new Object();
o.name=name;
return o;
}
然后, 当执行到b.showName();时, 就会抛出异常了, 因为 showName是prototype方法, 是指定在A的实例指针下的, 给A添加方法pointer()以获取实例的指针, 然后把它赋予B.prototype
function demo(){
var A=function(name){
this.name=name;
}
A.prototype.showName=function(){alert(this.name);} //the function return this, "this" is the pointer of instance
A.prototype.pointer=function(){return this;}
var B=function(name, age){
A.call(this, name);
this.age=age;
}
//B.prototype=new A();
//B.prototype=A.prototype;
B.prototype=new A().pointer();
B.prototype.showAge=function(){alert(this.age);}
var b=new B("david", 31);
b.showName();
b.showAge();
}
以上代码运行正常, 证明了prototype实质上就是指于实例的指针
那么, 如果, 把prototype的指针指于类, 又会如何呢, 我的想法是, 会得到类的静态方法或属性
以下代码, 给A添加静态方法showSex和静态属性city, 然后把A的类,
结果应该是A的原型方法showName会报错, 而b.showSex和alert(b.city)会得到正确的执行
function demo(){
var A=function(name){
this.name=name;
}
A.prototype.showName=function(){alert(this.name);} //the function return this, "this" is the pointer of instance
A.prototype.pointer=function(){return this;}
A.showSex=function(){alert("male");}
A.city="shenzhen";
var B=function(name, age){
A.call(this, name);
this.age=age;
}
//B.prototype=new A();
//B.prototype=A.prototype;
B.prototype=A;
B.prototype.showAge=function(){alert(this.age);}
var b=new B("david", 31);
try {
b.showName();
} catch (exception) {
alert(exception);
}
b.showAge();
b.showSex();
alert(b.city);
}
代码执行正常, 验证无误
再检验一下constructor
function demo(){
var A=function(name){
this.name=name;
}
A.prototype.showName=function(){alert(this.name);} //the function return this, "this" is the pointer of instance
A.prototype.showSex=function(){alert("male");}
A.prototype.city="shenzhen";
var B=function(name, age){
A.call(this, name);
this.age=age;
}
B.prototype=A.prototype;
B.prototype.showAge=function(){alert(this.age);}
var b=new B("david", 31);
try {
alert(b.constructor); //output Class A construct
alert(b.constructor==A);//output true
} catch (exception) {
alert(exception);
}
}
结果表明
alert(b.constructor), 连 B 的构造器都变成 A 的了
alert(b.constructor==A), 再比较一次, 输出true, 没有悬念了
继续挖掘, 把B.prototype=A, 即把A的类指针赋予B的prototype
function demo(){
var A=function(name){
this.name=name;
}
A.prototype.showName=function(){alert(this.name);} //the function return this, "this" is the pointer of instance
A.prototype.showSex=function(){alert("male");}
A.prototype.city="shenzhen";
var B=function(name, age){
A.call(this, name);
this.age=age;
}
B.prototype=A;
B.prototype.showAge=function(){alert(this.age);}
var b=new B("david", 31);
try {
alert(b.constructor==Function.constructor);//output true
alert(b.constructor); //output Function's constructor
} catch (exception) {
alert(exception);
}
}
结果表明, B.prototype指到类A的指针去了, 而类的指针, 又指向类的构造器了
再看看A, 被B"继承"后的样子, 在B.prototype=A的时候, this就已经是指向A了, showAge是不是也应该存在于A的实例呢? 在做个实验, 一个是A被继承前, 一个是A被继承后
function demo(){
var A=function(name){
this.name=name;
}
A.prototype.showName=function(){alert(this.name);} //the function return this, "this" is the pointer of instance
A.prototype.showSex=function(){alert("male");}
A.prototype.city="shenzhen";
var a=new A("mochacoffee");
var B=function(name, age){
A.call(this, name);
this.age=age;
}
B.prototype=A.prototype;
B.prototype.showAge=function(){alert(this.age);}
B.prototype.post="518000"; //add property for test
var c=new A("reno");
a.showAge(); //*1
alert(a.showAge); //*2
c.showAge(); //*3
alert(c.showAge); //*4
alert(a.post); //*5
alert(c.post); //*6
}
结果为:
1: undefined
2: function showAge(){...}
3: undefined
4: function showAge(){...}
5: 518000
6: 518000
可以看出, expend之前之后的A, 其实已经是一样了,
undefined, 是因为没有给变量赋值, 但函数指针已经正确指到B的showAge了
关于prototype也是, 对于a, 在被B继承后, 也可以获取了518000了, 用java语言来说, prototype只是实例指针而已, 而不论showAge还是post, 都是一个对象, 所以当a的指针指向这个"后来"加上的对象时, 当然也就可以得到518000了
但这样的话, B被继承A之后, A也得到了B的prototype了, 对于继承机制来说, 这样还算是继承吗? A和B的区别, 仅仅是静态方法和属性而已
分享到:
相关推荐
JS 中 prototype 的理解 prototype 是 JavaScript 中的一个重要概念,它是每个构造函数都有的一个属性,即原型。通过 prototype,可以实现继承和扩展对象的功能。prototype 的主要思想是,现在有 1 个类 A,我想要...
在JavaScript中,遍历属性、理解`prototype`和掌握继承机制是编程中不可或缺的基本技能。本文将深入探讨这些概念,并通过实例来加深理解。 首先,让我们来看如何遍历JavaScript对象的属性。JavaScript提供了多种...
理解并熟练掌握`prototype`,对于编写高效、可维护的JavaScript代码至关重要。通过`prototype`,开发者可以构建复杂的应用程序架构,利用原型链实现方法的复用和对象的层次结构。在实际开发中,结合`Object.create()...
理解`prototype`的概念,有助于深入掌握JavaScript的面向对象编程。 1. **原型链(Prototype Chain)** 当试图访问一个对象的属性时,JavaScript会首先在该对象自身的属性中查找。如果没有找到,它会检查该对象的`...
Prototype是JavaScript库,它为浏览器环境提供了强大的对象扩展和功能,尤其在处理DOM(文档对象模型)和Ajax交互时。这个压缩包包含了Prototype库的多个版本的手册和源代码文件,便于开发者理解和使用。 首先,...
Prototype JavaScript 框架是Web开发中的一个关键工具,...通过深入学习Prototype 1.6中文手册,并结合源码阅读,开发者不仅可以熟练掌握Prototype的用法,还能对JavaScript有更深入的理解,从而在实际项目中游刃有余。
**描述:** prototype.js 是一个JavaScript库,主要目的是为了简化JavaScript的开发,提升开发效率。它通过扩展JavaScript的基本对象和类型,提供了丰富的功能,包括类式继承、面向对象编程的支持以及一些实用的DOM...
### JS:prototype用法详解 #### 一、概念解析与基本使用 `prototype`是JavaScript中一个非常重要的概念,尤其自IE4及其后续版本引入以来,成为开发人员扩展内置对象功能的强大工具。`prototype`主要服务于面向...
《深入理解Prototype.js:JavaScript设计模式的基石》 Prototype.js是一个广泛使用的JavaScript库,它为JavaScript语言添加了许多实用的功能,增强了其在Web开发中的表现力。这个库的核心设计理念是通过扩展...
**《prototype.js中文手册》详解** Prototype.js 是一个开源JavaScript...《prototype.js中文手册》是深入理解并掌握这个库的宝贵资源,涵盖了从基础到高级的各种知识点,对于前端开发者来说是一本不可多得的参考书。
学习Prototype.js不仅能够提升JavaScript编程的效率,还能深入理解JavaScript的原型机制,这对于从事前端开发的工程师来说是必不可少的知识。通过这个压缩包,我们可以研究每个版本的变化,理解其设计理念,为自己的...
Prototype.js的丰富功能使得JavaScript开发更加便捷,通过深入理解和使用这些工具,开发者可以创建高效、交互性强的网页应用。在实践中,结合文档和示例代码,可以更好地掌握Prototype.js的精髓。
学习PrototypeJS不仅可以提高JavaScript编程效率,还能帮助你理解和掌握面向对象编程的概念,提升Web开发能力。通过深入研究提供的资料和实例,你将能够熟练运用PrototypeJS构建高效、动态的Web应用。
总的来说,《Prototype开发者手册(中文版)》结合Prototype.js库,为JavaScript开发者提供了丰富的资源和工具,帮助他们更高效地进行前端开发。无论是初学者还是经验丰富的开发者,都能从中受益,提升自己的...
`prototype.js`是一个开源库,旨在扩展JavaScript的基础功能,尤其是面向对象编程的支持。这个库由Sam Stephenson创建,是Prototype Library的一部分,广泛应用于Web应用开发中,尤其在Rails框架下的Ajax开发。 ###...
总结来说,《prototype.js源码及PDF文档》是JavaScript开发者的一份宝贵参考资料,它不仅提供了实际的代码示例,还有详细的理论指导,对于提升JavaScript技能和深入理解Prototype框架有极大的帮助。无论是初学者还是...
通过阅读提供的手册和查看源码,开发者可以深入理解JavaScript的面向对象编程,并学会如何有效地利用Prototype进行Web应用开发。无论是初学者还是经验丰富的开发者,这个库都提供了丰富的资源和工具来提升开发效率。
Prototype.js文件是这个库的核心,它包含了大量的实用函数和扩展,使得JavaScript编程更加高效且易于维护。 Prototype库的核心理念是扩展JavaScript的基本类型和对象,以便在进行DOM操作、事件处理、Ajax通信等方面...
### Prototype.js学习从简单开始:元素定位与DOM操作 #### 引言 随着Web开发的不断进化,Ajax技术成为提升用户体验的重要工具。...此外,深入理解JavaScript语言本身,将使你在使用Prototype.js时更加得心应手。