当前位置: 首页 > 编程日记 > 正文

在Javascript中使用面向对象的编程

by Mike Koss
March 26th, 2003

这是一篇,我个人认为最好的,Javascript面向对象编程的文章。翻译不好的地方,还望大家指正,谢谢。
如果您需要,可以访问下面的地址取得原文: http://mckoss.com/jscript/object.htm
在我的blog里,将会陆续推出这个理论的实践、源码。

介绍

大部分的Javascript的编写者,都只是把它做为简单的脚本引擎,来创建动态的Web页面。同时Web设计人员开始使用在IE浏览器中定义的对象模型,来处理Web页面的内容。但是大多数的开发者并没有认识到Javascript在其自身就具有强大的面向对象的功能。当不使用强类型的时候(变量不必先声明后使用),这种解析性的语言,可以巧妙的达成面向对象(object-oriented)的功能,包括:

  • 封装 (Encapsulation)
  • 多台 (Polymorphism )
  • 继承 (Inheritance)

虽然,通过一系列的范例(对于好奇的读者,这些范例片断代码是很生动的),我将会阐述对象在Javascript中,对象是如何被使用,并且如何实现面向对象的。

简单对象(Simple Objects)

在Javascript中,最简单的可构建的对象,就是机制内建的Object对象。在Javascript中,对象是指定名称的属性(property)的集合。做为解析性语言,Javascript允许给一个对象创建任意个属性,在任何时间(不像C++,它的属性是可以在任何时间添加给对象。它们并不需要事先在对象的声明(definition)或者构造(constructor)中,进行定义)。

所以,举例来说,我们可以创建一个对象,然后添加一系列的属性给它,就像这样:

obj = new Object;<br><br>obj.x = 1;<br><br>obj.y = 2;

这里,Javascript对象,可以用图形表示成这样的结构:

obj
x1
y2
prototype properties
constructor
function Object

另外需要注意的是,我们创建的x和y属性, 我们的对象默认有一个属性constructor t他指向一个Javascript内部对象函数(funciton)。 (译者注:prototype,原型在后文会有进一步的说明)

对象的构造函数(Object Constructors)

对于要定义的对象类型,Javascript允许我们自己给对象类型定义构造函数:

function Foo()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.x = 1;<br><br>&nbsp;&nbsp;&nbsp; this.y = 2;<br><br>}<br><br> <br><br>obj1 = new Foo;<br><br>
obj1
x1
y2
prototype properties
constructorfunction Foo

这里要说明的是,我们可以创建任意多个Foo类型的对象实例,它们也都将分别初始化自己的x和y属性为1和2。

简单的方法的的实现(A Simple Method Implementation)

为了封装对象的行为功能,向调用者隐藏执行过程,我们需要给对象创建方法(method)。Javascript允许你将任意一个函数(function)分配给对象的一个属性。当我们使用 obj.Function 的语法调用函数的时候,将把函数原来定义this 的指向,当前这个对象(就像它在构造函数中的那样)。

function Foo()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.x = 1;<br><br>&nbsp;&nbsp;&nbsp; this.y = 2;<br><br>&nbsp;&nbsp;&nbsp; this.Bar = MyMethod;<br><br>}<br><br> <br><br>function MyMethod(z)<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.x += z;<br><br>}<br><br> <br><br>obj2 = new Foo;<br><br>
obj2
x1
y2
Barfunction MyMethod
prototype properties
constructorfunction Foo

现在,我们简单的调用一下,做为对象的方法的Bar函数:

obj2.Bar(3);<br><br>
obj2
x4
y2
Barfunction MyMethod
prototype properties
constructorfunction Foo

所以,你可以方便的给对象定义构造函数和方法,使其对调用者而言,隐藏它的实现过程。同样的,因为,Javascript不是强类型的,所以,我们可以通过定义有相同名字的方法的对象,来简单的实现多台性(polymorphism)。

function Foo()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.x = 1;<br><br>&nbsp;&nbsp;&nbsp; this.DoIt = FooMethod;<br><br>}<br><br> <br><br>function FooMethod()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.x++;<br><br>}<br><br> <br><br>function Bar()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.z = 'Hello';<br><br>&nbsp;&nbsp;&nbsp; this.DoIt = BarMethod;<br><br>}<br><br> <br><br>function BarMethod()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.z += this.z;<br><br>}<br><br> <br><br>obj1 = new Foo;<br><br>obj2 = new Bar;<br><br>
obj1
x1
DoItfunction FooMethod
prototype properties
constructorfunction Foo
obj2
zHello
DoItfunction BarMethod
prototype properties
constructorfunction Bar
function Poly(obj)<br><br>{<br><br>&nbsp;&nbsp;&nbsp; obj.DoIt();<br><br>}<br><br> <br><br>Poly(obj1);<br><br>Poly(obj2);<br><br>
obj1
x2
DoItfunction FooMethod
prototype properties
constructorfunction Foo
obj2
zHelloHello
DoItfunction BarMethod
prototype properties
constructorfunction Bar

使用原型实现方法(Using Prototypes to Implement Methods)

试想一下,这使很笨的办法,每次我们都要创建名称没有使用意义的方法函数,然后在构造函数里,把它们分配给每个方法属性。其实,我发现使用Javascript的原型(prototype)机制,是更为直接的方法。

每个对象,可以参照一个原型对象,原型对象包含有自己的属性。它就好比是一个对象定义的备份。当代码,引用一个属性的时候,它并不存在于对象本身里,那么Javascript将会自动的在原型的定义中查找这个属性。而且,事实上,一个对象的原型对象又可以参照另外一个原型对象,就这样以链式最终关联到基类对象的构造函数。(译者注:对于DOM对象等系统的对象,原型对象可以修改,但是不可以赋值改变的,只有自定义对象可以。)这是template模型(译者注:模板方法,《设计模式》中行为模式的一种),它可以简化我们对方法的定义,同时也可以产生强大的继承机制。

在Javascript中,原型对象是被分配给构造函数的。所以,为了修改对象的原型,必须首先修改构造函数的原型对象的成员。然后,当对象从构造函数被构造的时候,对象将会引用到构造函数的原型。

function Foo()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.x = 1;<br><br>}<br><br> <br><br>Foo.prototype.y = 2;<br><br>obj = new Foo;<br><br>document.write('obj.y = ' + obj.y);<br><br>
obj.y = 2
obj
x1
prototype properties
constructorfunction Foo
prototype
y2
y2

即使我们并没有直接的把y属性分配给obj,obj对象仍然有一个y属性。当我们引用obj.y的时候,Javascript实际返回obj.constructor.prototype.y的引用。我们可以肯定的是,原型的值的改变,也将会反映到对象中。

Foo.prototype.y = 3;<br><br>document.write('obj.y = ' + obj.y);<br><br>
obj.y = 3
obj
x1
prototype properties
constructorfunction Foo
prototype
y3
y3
我们也可以发现,一旦我们初始化一个属性的“私有”( private )的值,存放在原型中的值并不会收到影响:
obj.y = 4;<br><br>Foo.prototype.y = 3;<br><br>
obj
x1
y4
prototype properties
constructorfunction Foo
prototype
y3

原型方法的命名(Prototype Method Naming)

我发现了可以直接定义类的原型的方法的语句,而不需要单独的函数的名称:

function Foo()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.x = 1;<br><br>}<br><br> <br><br>function Foo.prototype.DoIt()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.x++;<br><br>}<br><br>obj = new Foo;<br><br>obj.DoIt();
obj
x2
prototype properties
constructorfunction Foo
prototype
DoItfunction Foo.prototype.DoIt
DoItfunction Foo.prototype.DoIt

基于原型的子类继承(Prototype-based Subclassing )

一旦可以建立原型对象链,我们就可以使用它做为对象的子类的类型。这个方法要注意的是,我们创建了一个基类对象的实例,并把它做为我们的类的构造函数的原型对象。这么做,我们所创建的所有的对象,将继承基类对象的所有成员和(方法)。但是要注意,基类的构造函数只会被调用一次(译者注:从基类到子类的构造函数都是唯一的,即基类的构造函数)。这不像C++,基类的构造函数,对于每个继承的子类,都可以分别的调用。在后面,我将展示,当独立的构造函数被需要的时候,另外一种可选的方式来创建继承类。
function TextObject(st)<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.st = st;<br><br>&nbsp;&nbsp;&nbsp; this.fVisible = true;<br><br>}<br><br> <br><br>function TextObject.prototype.Write()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; document.write('<br><br>' + this.st);<br><br>}<br><br> <br><br>function ItalicTextObject(st)<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.st = st;<br><br>}<br><br> <br><br>ItalicTextObject.prototype = new TextObject('x');<br><br> <br><br>ItalicTextObject.prototype.Write = ITOWrite;<br><br>function ITOWrite()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; document.write('<br><br><em>' + this.st + '</em>');<br><br>}<br><br> <br><br>obj1 = new TextObject('Hello, mom');<br><br>obj2 = new ItalicTextObject('Hello, world');<br><br>obj1.Write();<br><br>obj2.Write();<br><br>

Hello, mom
Hello, world
obj1
stHello, mom
fVisibletrue
prototype properties
constructorfunction TextObject
prototype
Writefunction TextObject.prototype.Write
Writefunction TextObject.prototype.Write
obj2
stHello, world
prototype properties
constructorfunction TextObject
prototype
Writefunction TextObject.prototype.Write
fVisibletrue
Writefunction ITOWrite
这个结构存在两个问题。一个是,当每次构造继承的类的时候,基类的构造函数都不会被调用。假如,构造函数不做太多的事情,只是初始化一些成员变量为静态的值,这个问题就不是太明显了。第二个,注意,我将不能使用"function Obj.prototype.Method"的方式,来定义继承类的成员。这是因为,对于构造函数来说,我要把这些方法的定义,放入新创建的原型对象,而不是添加到,默认的原型对象。

另一种子类继承方式(An Alternate Subclassing Paradigm)

我们可以提出一种方法,更类似于反映C++类的概念和子类的定义,以及从子类反向存取基类的纯原型链的风格。它需要添加新的方法DeriveFrom给基类。
function Function.prototype.DeriveFrom(fnBase)<br><br><br><br>{<br><br><br><br>&nbsp;&nbsp;&nbsp; var prop;<br><br><br><br><br><br><br><br>&nbsp;&nbsp;&nbsp; if (this == fnBase)<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert("Error - cannot derive from self");<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br><br><br><br><br><br><br>&nbsp;&nbsp;&nbsp; for (prop in fnBase.prototype)<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (typeof(fnBase.prototype[prop]) == "function" &amp;&amp; !this.prototype[prop])<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.prototype[prop] = fnBase.prototype[prop];<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br><br><br><br><br><br><br>&nbsp;&nbsp;&nbsp; this.prototype[fnBase.StName()] = fnBase;<br><br><br><br>}function Function.prototype.StName()<br><br><br><br>{<br><br><br><br>&nbsp;&nbsp;&nbsp; var st;<br><br><br><br><br><br><br><br>&nbsp;&nbsp;&nbsp; st = this.toString();<br><br><br><br>&nbsp;&nbsp;&nbsp; st = st.substring(st.indexOf(" ")+1, st.indexOf("("))<br><br><br><br><br><br><br><br>&nbsp;&nbsp;&nbsp; return st;<br><br><br><br>}function TextObject(st)<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.st = st;<br><br>&nbsp;&nbsp;&nbsp; this.fVisible = true;<br><br>}<br><br> <br><br>function TextObject.prototype.Write()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; document.write('<br><br>' + this.st);<br><br>}<br><br> <br><br>function TextObject.prototype.IsVisible()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; return this.fVisible;<br><br>}<br><br> <br><br>function ItalicTextObject(st)<br><br>{<br><br>&nbsp;&nbsp;&nbsp; this.TextObject(st);<br><br>}<br><br> <br><br>ItalicTextObject.DeriveFrom(TextObject);<br><br> <br><br>function ItalicTextObject.prototype.Write()<br><br>{<br><br>&nbsp;&nbsp;&nbsp; document.write('<br><br><em>' + this.st + '</em>');<br><br>}<br><br> <br><br>obj1 = new TextObject('Hello, mom');<br><br>obj2 = new ItalicTextObject('Hello, world');<br><br>obj1.Write();<br><br>obj2.Write();<br><br>

Hello, mom
Hello, world
obj1
stHello, mom
fVisibletrue
prototype properties
constructorfunction TextObject
prototype
Writefunction TextObject.prototype.Write
IsVisiblefunction TextObject.prototype.IsVisible
IsVisiblefunction TextObject.prototype.IsVisible
Writefunction TextObject.prototype.Write
obj2
stHello, world
fVisibletrue
prototype properties
constructorfunction ItalicTextObject
prototype
Writefunction ItalicTextObject.prototype.Write
IsVisiblefunction TextObject.prototype.IsVisible
TextObjectfunction TextObject
prototype
Writefunction TextObject.prototype.Write
IsVisiblefunction TextObject.prototype.IsVisible
IsVisiblefunction TextObject.prototype.IsVisible
TextObjectfunction TextObject
prototype
Writefunction TextObject.prototype.Write
IsVisiblefunction TextObject.prototype.IsVisible
Writefunction ItalicTextObject.prototype.Write
我们还得到了一个额外的好处,那就是,我们可以从多个基类进行继承(多重的继承)。

相关文章:

马斯克嘲笑「元宇宙」的想法,并给年轻人5条鸡汤

编译 | 禾木木出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;SpaceX 和特斯拉的CEO 马斯克在接受 The Babylon Bee 的采访中&#xff0c;当被问到元宇宙的问题时&#xff0c;马斯克只笑了笑。马斯克表示&#xff1a;“我对元宇宙这个概念没有什么印象&#xff0c;尽…

OpenLDAP自定义属性的启用

2019独角兽企业重金招聘Python工程师标准>>> # ucode# This multivalued field is used to record the values of the license or# registration plate associated with an individual.attributetype ( 2.16.840.1.113730.3.1.900 NAME ucode DESC user code …

硬中断与软中断的区别!

硬中断&#xff1a; 1. 硬中断是由硬件产生的&#xff0c;比如&#xff0c;像磁盘&#xff0c;网卡&#xff0c;键盘&#xff0c;时钟等。每个设备或设备集都有它自己的IRQ&#xff08;中断请求&#xff09;。基于IRQ&#xff0c;CPU可以将相应的请求分发到对应的硬件驱动上&am…

smarty模板

<?phprequire(../libs/Smarty.class.php);$smarty new Smarty;//$smarty->force_compile true;//$smarty->debugging true;//$smarty->caching true;//$smarty->cache_lifetime 120;$Name"Linux环境高级编程";$smarty->assign("name&qu…

乘“云原生”之风、踏“数字化”的浪,《新程序员003》开启预售!

12月30日&#xff0c;新年的钟声还有两天敲响&#xff0c;CSDN倾情策划出品的《新程序员003&#xff1a;云原生和全面数字化实践》&#xff08;以下简称《新程序员003》&#xff09;重磅开启预售&#xff01;新一年&#xff0c;新气象~预祝所有开发者在新的一年中大神附体&…

BZOJ4245 : [ONTAK2015]OR-XOR

按位考虑&#xff0c;逐步确定答案。 设当前是第i位&#xff0c;求出第i位的前缀异或和。 若存在m个0且所有数字异或和为0&#xff0c;那么答案的这一位可以为0&#xff0c;并把所有1的位置给标记为不可选。 否则答案的这一位只能是1。 时间复杂度$O(n\log n)$。 #include<c…

关键词排名下降怎么办-优八学院给你支招

优八学院下面为大家解决一下关于关键词排名下降的问题。在我们进行网站优化的时候&#xff0c;往往会出现关键词排名下降的现象。对于这种情况&#xff0c;我们要区别是否是正常的浮动&#xff0c;由于有时候搜索引擎也会发生错误&#xff0c;导致关键词排名下降&#xff0c;我…

全面解析 Kmeans 聚类算法(Python)

作者 | 泳鱼来源 | 算法进阶一、聚类简介Clustering (聚类)是常见的unsupervised learning (无监督学习)方法&#xff0c;简单地说就是把相似的数据样本分到一组&#xff08;簇&#xff09;&#xff0c;聚类的过程&#xff0c;我们并不清楚某一类是什么&#xff08;通常无标签信…

.htaccess的重写规则

.htaccess基本语法和应用 .htaccess是Apache服务器的一个非常强大的分布式配置文件。正确的理解和使用.htaccess文件&#xff0c;可以帮助我们优化自己的服务器或者虚拟主机。 如何启用htaccess 以windows为例&#xff0c;进入apache/conf目录&#xff0c;找到httpd.conf文件&a…

amaze ui各个模块简单说明

amaze ui各个模块简单说明 导航添加依据 http://amazeui.org/css/ 下面内容属学习笔记&#xff0c;如有理解偏差和错误请留言相告&#xff0c;感谢&#xff01;* &#xff08;官网这块写的很详细&#xff09; 一、基本样式 1.统一样式 说明了为什么使用Normalize&#xff0c;而…

由浅入深剖析.htaccess

1、.htaccess文件使用前提.htaccess的主要作用就是实现url改写&#xff0c;也就是当浏览器通过url访问到服务器某个文件夹时&#xff0c;作为主人&#xff0c;我们可以来接待这个url&#xff0c;具体地怎样接待它&#xff0c;就是此文件的作用。所有的访问都是通过URL实现&…

分享几个 Pyecharts 技巧,助你画出更直观/炫酷的图表

作者 | 俊欣来源 | 关于数据分析与可视化想必大家应该也已经看到很多关于数据分析的内容了&#xff0c;今天小编就为大家来分享一下国产可视化库pyecharts在绘制图表时一些的技巧&#xff0c;帮助读者画出更加酷炫以及可读性更高的图&#xff0c;当然在这之前呢&#xff0c;我们…

虚拟化--006 VCAC的sso配置成功

转载于:https://blog.51cto.com/williamliuwen/1686492

ionic app 开发和生产环境的配置

前言 像 Angular2 一样&#xff0c;希望 ionic 可以提供 2 个文件 ( environment.dev.ts 和 environment.prod.ts )&#xff0c;其中包含与开发和生产环境相对应的不同值的变量。在构建过程中&#xff0c;要在应用程序中绑定适当的文件。 实现步骤 在 src/config 中&#xff0c…

Android Properties 存储

1.初始化 1 private static void initProperties(){2 File logFile new File(Constants.PROGRESS_PROPERTIES);3 props new Properties();4 if(!logFile.exists()){5 //创建并初始化配置文件6 FileUtils.createFolder(Const…

php函数serialize()与unserialize()

php函数serialize()与unserialize()说明及案例。想要将已序列化的字符串变回 PHP 的值&#xff0c;可使用unserialize()。serialize()可处理除了resource之外的任何类型。甚至可以serialize()那些包含了指向其自身引用的数组。你正serialize()的数组&#xff0f;对象中的引用也…

2500 字全方面解读 Python 的格式化输出

作者 | 欣一来源 | Python爱好者集中营今天小编来和大家聊聊Python当中的格式化输出&#xff0c;希望会对大家所有帮助%占位符的使用我们先来看一下下面的这个例子&#xff0c;country_ "France" currency_ "Euro"print("%s is the currency of %s&…

python GUI编程( 二 ) (基于PyQt5)

第二节 本节介绍添加窗口图标&#xff0c;在窗口内添加按钮&#xff0c;在窗口内添加提示框。 导入模块&#xff1a; from PyQt5.QWidgets import QWidget,QPushButton,QApplication from PyQt5.QtGui import QIcon,QFont from PyQt5.QtCore import QCoreApplication import sy…

Linux+Apache2+openssl实现https验证

首先安装SSL&#xff0c;再编译安装APACHE&#xff0c;再配置证书即可 1.下载apache和openssl网址&#xff1a;http://www.apache.org http://www.openssl.org2.解压#tar zxvf httpd-2.0.54.tar.gz#tar zxvf openssl-0.9.7g.tar.gz3.编译安装openssl,这个软件主要是用来生…

践行科技向善,腾讯Light 把光引向厦门

作者 | 贾凯强出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;凛冬虽至&#xff0c;但沿着东南海域一路向南&#xff0c;总有寒风吹不灭的绿意&#xff0c;也有四季不败落的花香。今年的冬天厦门始终环绕着勃勃生机&#xff0c;也有无数的追光者来到了这里。因为关注…

【每天一点点】

>>>html 使用使用<a href"URL">ba bla bla</a>定义资源位置&#xff0c;使用<a href"#name"></a>跳转到name锚所在的位置&#xff1b;>>>eclipse的注释快捷键 方法一&#xff1a;使用Ctrl/快捷键&#xff0c;使…

模式的秘密-观察者模式(四)

区别对待观察者场景问题 两点需求&#xff1a; 第一&#xff1a;黄明女朋友只想接收下雨的天气预报。 第二&#xff1a;黄明老妈&#xff0c;想接收下雨或者下雪的天气预报。 解决思路&#xff1a; 情况之一&#xff1a; 如果天气晴天&#xff0c;按照黄明女朋友需要下雨添加&a…

PHP Webservice的发布与调用

PHP Webservice的发布与调用1. 环境配置 配置php.ini&#xff0c;把php_soap.dll前面的分号去掉&#xff0c;不然会报错 class soapserver not found重启apache后通过phpinfo()查看 这样是表示环境已经支持soap的webservice了&#xff0c;后面的事情就是写代码了。2. webserv…

全球首家!苹果市值达 3 万亿美元,创历史新高

作者 | 苏宓出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;成立于 1976 年的苹果公司&#xff0c;耗时 44 年&#xff0c;终于在 2018 年首次达到 1 万亿美元的市值。自此之后&#xff0c;苹果的发展仿佛安装了“高速马达”&#xff0c;短短两年后的 2020 年 8 月…

Add Digits

题干就是给一个非负整数&#xff0c;把各位数加起来&#xff0c;若超过一位&#xff0c;则继续把各位加起来&#xff0c;直到和是一位数。 example&#xff1a; 39->12->3 坦白说我是看了第三个提示意识到的&#xff0c;所以说要找规律&#xff0c;先要暴力列举。 int ad…

JAVA多线程之Synchronized、wait、notify实例讲解

一、Synchronized synchronized中文解释是同步&#xff0c;那么什么是同步呢&#xff0c;解释就是程序中用于控制不同线程间操作发生相对顺序的机制&#xff0c;通俗来讲就是2点&#xff0c;第一要有多线程&#xff0c;第二当多个线程同时竞争某个资源的时候会有先后顺序。在ja…

匹夫细说C#:委托的简化语法,聊聊匿名方法和闭包

0x00 前言 通过上一篇博客《匹夫细说C#&#xff1a;庖丁解牛聊委托&#xff0c;那些编译器藏的和U3D给的》的内容&#xff0c;我们实现了使用委托来构建我们自己的消息系统的过程。但是在日常的开发中&#xff0c;仍然有很多开发者因为这样或那样的原因而选择疏远委托&#xff…

20个案例详解 Pandas 当中的数据统计分析与排序

作者 | 俊欣来源 | 关于数据分析与可视化今天小编来给大家讲一下Pandas模块当中的数据统计与排序&#xff0c;说到具体的就是value_counts()方法以及sort_values()方法。value_counts()方法&#xff0c;顾名思义&#xff0c;主要是用于计算各个类别出现的次数的&#xff0c;而s…

zend studio 8安装与汉化

http://archive.eclipse.org/technology/babel/update-site/R0.8.0/helios正确操作&#xff1a;1、大家可以用这个地址作为更新源&#xff08;操作&#xff1a;菜单栏中window->property->Installation/update->update 添加这个地址&#xff0c;并打勾&#xff09; 2、…

分享一个电视节目API接口PHP调用代码

央视及各地卫视的电视节目时间表&#xff0c;包括本周及下周的电视节目内容 获取电视台分类 复制代码 获取电视频道 复制代码 获取电视节目的详情 复制代码 注意&#xff0c;该示例代码适用于 www.apishop.net网站下API 使用该产品前&#xff0c;您需要通过 https://…