文档章节

关于Python的类成员和Javascript的原型

Shawphy
 Shawphy
发布于 2011/08/30 09:34
字数 1435
阅读 223
收藏 0

      偶然发现两个的设计思路是一致的(个人理解,欢迎指正)。这里简要分析一下:

      Python的类成员,也就是直接定义在类里的变量(实例成员是用self.x直接声明的),而类方法就是用@classmethod说明的方法。

Python还有一种@staticmethod,静态方法,其实设立所有的静态方法和变量的目的主要是用类名限制访问范围,编译的时候就直接被改名然后变成了全局变量。

      Js的原型(prototype)是js里最复杂的一部分了,有的人可能Jquery什么的用的很熟,但是对原型一无所知。最初设计Js的时候设计师没有考虑把它设计成一门完整的语言,后来决定引入面向对象的时候,就采用了原型链这种诡异的设计模式。具体的使用大家应该都熟悉。类名(实际是函数名).prototype.x=…,这样就在类的原型上加入了一方法或成员。

实际Js也有静态方法和静态变量,就是通过类名.x=…定义的,跟一切静态方法一致,也只是限制了范围,最终会改名并变成全局变量。

      我们只讨论类成员类方法,静态的不在我们考虑范围之内,这种类即对象的设计理念,主流语言里貌似只有Js,Python和Perl采用了,跟静态方法是完全不同的理念。

      首先,我们要问为什么要引入类方法和类成员,它跟实例方法实际成员有什么不同呢?

      这里我们要建立一个概念,在Python和Js里,类也是一种对象(实例)(我的世界观颠覆了)。类其实相当于一个模板,只不过大多数语言里,我们通过类实例化出一个一个对象,抛去静态的,这些对象是各不相同的(先考虑成员对象,方法都是共享的)。而Python和Js里,这些对象共同引用类模板里的对象(及方法)。类模板好比一个公共的祖先,从这个祖先衍生的实例都有相同的血缘(共同的prototype),但是各自有自己不同的部分。

     不知道这么说是否清晰,我们举两个例子:

     Python的[1]:

class Demo:
    i = 0
    def __init__(self):
        self.j = 0
o1 = Demo()
o2 = Demo()

Demo.i = 10 #类成员的赋值print o1.i #结果为10,说明在没有显式定义实例成员的时候,就会取类成员的值print o2.i #结果为10,说明在没有显式定义实例成员的时候,就会取类成员的值

o1.i = 1 #会为o1对象创建实例成员。
o2.i = 2 #会为o2对象创建实例成员
o1.j = 11
o2.j = 12print o1.i # 结果为1print o2.i # 结果为2   这两个结果说明对i数据成员的赋值,每个对象都有自己的实例成员。print Demo.i #结果为10说明,前边的赋值,并没有覆盖该类成员。print o1.j # 结果为 11print o2.j # 结果为 12 正常的实例成员访问。

       结果很清晰,类成员大家共享,但是各自有各自不同的实例成员,类成员可以通过实例调用,这时候就存在了命名冲突了怎么办的问题,于是实例成员覆盖类成员,没有实例成员的时候才调用类成员,而通过类名调用类成员是最正统的方法了,毕竟Python里类也是对象,你把类名想象成一个直接被实例化了的原型对象,就好理解多了。

      然后举一个Js的例子[2]

var BaseClass = function() {this.method1 = function(){
       alert(' Defined by the "this" in the instance method');
 }
};var instance1 = new BaseClass();
instance1.method1 = function(){
    alert(' Defined directly in the instance method');
}
BaseClass.prototype.method1 = function(){
    alert(' Defined by the prototype instance method ');
}
instance1.method1();//Defined directly in the instance method  

通过运行结果跟踪测试可以看出直接定义在实例上的变量的优先级要高于定义在“this”上的,而定义在“this”上的又高于 prototype定义的变量。即直接定义在实例上的变量会覆盖定义在“this”上和prototype定义的变量,定义在“this”上的会覆盖prototype定义的变量。

        这与Python的例子思想一致。原型相当于类模板,实例共享原型,通过实例名调用一个方法时,如果出现命名混淆,实例的方法也会覆盖原型的方法。同样,实例同名成员的改动并不会影响原型成员,验证如下。而且原型最正统的调用方法也是通过类名,而不是实例名。

 

function ec(str) {
	document.write(str+"<br/>");
}var test= function(){
}
test.prototype.age = 11;var t=new test();var s=new test();

ec(t.age);
ec(s.age);

t.age=12;
s.age=13;

ec(t.age);
ec(s.age);
ec(test.prototype.age);

       有了这种理解,阮一峰的三篇关于Js面向对象设计思想的文章也就不那么费解了。

       最后,吐个槽:Python真是纯面向对象啊,纯的……

参考文献:

[1] python中类中的静态数据成员和实例数据成员

http://hi.baidu.com/chaseagle/blog/item/d2ae46dacbd64addb6fd48e9.html

(注:实际上是类数据成员而不是静态)

[2] javascript中静态方法、实例方法、内部方法和原型的一点见解

http://linder0209.iteye.com/blog/1076172

[3] 阮一峰,Javascript 面向对象编程(一):封装

http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html

[4] 阮一峰,Javascript面向对象编程(二):构造函数的继承

http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html

[5] 阮一峰,Javascript面向对象编程(三):非构造函数的继承

http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance_continued.html

© 著作权归作者所有

共有 人打赏支持
Shawphy
粉丝 3
博文 25
码字总数 10170
作品 0
海淀
程序员
私信 提问
加载中

评论(2)

Shawphy
Shawphy

引用来自“Mr.kimilo”的评论

你上面的文章,我恰好也看了,在弄javascript,求交流。

略懂而已...
滴滴丶哔哔
滴滴丶哔哔
你上面的文章,我恰好也看了,在弄javascript,求交流。
Python 与 Javascript 之比较

最近由于工作的需要开始开发一些Python的东西,由于之前一直在使用Javascript,所以会不自觉的使用一些Javascript的概念,语法什么的,经常掉到坑里。我觉得对于从Javascript转到Python,有必...

naughty
2014/05/13
0
39
使用面向对象技术创建高级Web应用程序

最近,我面试了一位具有5年Web应用开发经验的软件开发人员。她有4年半的JavaScript编程经验,自认为自己具有非常优秀的JavaScript技能,可是,随后我很快发现,实际上她对JavaScript却知之甚...

时过境迁_
2013/06/20
11.7K
41
JavaScript装饰器 Decorator

前言 许多面向对象都有decorator(装饰器)函数,比如python中也可以用decorator函数来强化代码,decorator相当于一个高阶函数,接收一个函数,返回一个被装饰后的函数。 下面的示例代码,就是...

ITgecko
2018/05/22
0
0
无需图形界面环境下的浏览器项目一览表

本表几乎列出了所有无需图形界面环境下的浏览器开源项目,可用于自动化、测试或者其他用途。 软件名 介绍 支持语言 Awesomium 基于Chromium无图形界面浏览器引擎。 C++, .NET benv Benv是nod...

oschina
2016/07/27
13.5K
18
Dart 之于 JavaScript 正如 C# 之于 C++

版权声明:本文为 OSChina.NET 原创编译 转载务必注明出处,并保留链接! Dart之于JavaScript正如C #之于C++ 在谷歌工程师拉尔斯·巴克(Lars Bak)的V8 JavaScript解释器颠覆了Firefox所宣称...

虫虫
2011/10/20
3.5K
22

没有更多内容

加载失败,请刷新页面

加载更多

小程序-星星评分

//UI界面 <block wx:for='{{item.rateArray}}' wx:key wx:for-item="i" > <image wx:if='{{ i==0}}' src='../../assets/xing4.png'></image> <image wx:if='{{ i==1}}' src='../../assets/xi......

lsy999
30分钟前
1
0
JavaScript与WebAssembly进行比较

本文由云+社区发表 作者:QQ音乐前端团队 在识别和描述核心元素的过程中,我们分享了构建SessionStack时使用的一些经验法则,这是一个轻量级但健壮且高性能的JavaScript应用程序,以帮助用户...

腾讯云加社区
31分钟前
4
0
如何设计一个 RPC 系统

RPC是一种方便的网络通信编程模型,由于和编程语言的高度结合,大大减少了处理网络数据的复杂度,让代码可读性也有可观的提高。但是RPC本身的构成却比较复杂,由于受到编程语言、网络模型、使...

编程SHA
32分钟前
2
0
API权限控制与安全管理

一、API权限控制范围 1、首先验证web端请求参数: (1)web请求参数:渠道、ServiceName、版本、Airline、时间戳(yyyyMMddhhmmssSSS)、reqXML、Language、签名 (2)请求不能为空,并且格式...

Jack088
33分钟前
2
0
最热门的13个Java微服务框架

曾经的服务器领域有许多不同的芯片架构和操作系统,经过长期发展,Java的“一次编译,到处运行”使得它在服务器领域找到一席之地,成为程序员们的最爱 本文,我们将和大家分享13个可靠的Jav...

java菜分享
33分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部