标签存档: Javascript

5,316 查看

Javascript中Function,Object,Prototypes,__proto__等概念详解

Javascript中Function,Object,Prototypes,__proto__等概念是在JavaScript中很常用,但又总是不清不楚的概念。今天主要是解释他们之间的概念和关系,帮助我们更好的理解Javascript。 我们本次的解释,主要通过下图 粗看该图,估计你不一定能看明白。不过接下来让我逐行向你解释。 【第一行】 最左侧:意思是,有两个对象f1和f2,他们是通过new Foo()出来的。 中间:Foo()就是最左侧用到的Foo() 最右侧:表示,函数的prototype属性,对是函数的,不是对象的,站点要注意! 现在知道了各个区块的意思,接下来解释各条线是什么意思。 1、__proto__的虚线:该条线表示通过f1.__proto__可以访问到Foo.prototype,其实两者是等价的,我们可以通过以下代码验证。 function Foo(){ } var f1=new Foo(); alert(f1.__proto__==Foo.prototype);//true 2、prototype实线:表示通过Foo.prototype可以找到Foo.prototype。这里没有写错,这么写虽然看似有些废话,但是是要体现出流向的。 3、constructor实现:表示通过Foo.prototype.constructor可以找到Foo。验证代码如下: function Foo(){ } alert(Foo==Foo.prototype.constructor);//true 其中的意义在于f1.__proto__.constructor等于Foo 至此第一行结束了。 【插播】 在讲解下面第二行和第三行前,有两个很重要的概念需要深刻理解。否则理解下面的内容是举步维艰的。 Function和Object function Object(){[native code]}//Javascript自带,不是自定义的,可以近似认为是基类 function Function(){[native code]}//Javascript自带,不是自定义的,可以近似认为是基类 这里的这两个function,分别走两个方向, Object作为了众多object(实例,new出来的)的基类型 Function作为众多function(主要是那些function出来的,就是定义出来的函数)的基类型 在开始下面更细致的解释先,我们约定一些内容,Object代表这里所说的Object,object代表实例对象 ,Function代表这里说的Function,function是关键字。对于Object与object的区别很好理解,一个是function,一个是new出来。 现在让我们思考两个问题: …

继续阅读 »

2,127 查看

闭包(Closure)详解及Javascript静态变量实现分析

闭包这一词很抽象,事实上概念并不抽象,但是应用起来还真的是很抽象。 先来看看定义(引自百度百科): 闭包是可以包含自由变(未绑定到特定对象)量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在代码块的环境中定义。“闭包”一词来源于以下两者的结合:要执行的代码块和自由变量提供绑定的计算环境。   读完后感觉困惑是很正常的,我现在来好好解释下。 为了方便解释,我们给定义中出现的角色赋上代号,首先我们命名闭包为snippet,包含的自由变量为fvar,全局上下文变量统称为globals,代码块环境是context。 根据定义,我们可以如下改述: snippet含有fvar,此fvar在snippet中没有定义,同时globals中也不含有fvar的定义,所以,当我们单看snippet时候,你会发现fvar是一个未定义的变量。当我们把snippet放到context中,为了让其正常执行,我们需要补全fvar的定义,但又不能在snippet中定义。所以就要在context中定义。   有了上面改述的内容,我们再看一个实例,来加深理解,下面的代码,我使用JavaScript解释: var displayItemName=function(item){ var itemDefault = “default”; var closure1 = function(){ alert(item); } var closure2 = function(){ alert(itemDefault); } closure1(); closure2(); } displayItemName(“football”)   这里的displayItemName函数对应context,这里没有globals,closure对应我们前面说的snippet,closure中的item和itemDefault,对于closure来说是自由变量,也即对应fvar。但是对于context(displayItemName函数)来说,不是自由变量,并在其中定义了。   从这么多角度说,应该能搞清楚闭包的意思了。接下来我们用一句话总结闭包(针对JavaScript),就是: 在一个函数(父函数)中,定义另一个函数(子函数),子函数用到了父函数的变量,但自己并没有重新定义此变量,此时称该子函数为一个闭包。   上面的定义应该比原本的定义好理解多了,但要注意这主要是根据JavaScript的特性总结的,不同的语言室不同的。   …

继续阅读 »

762 查看

Javascript中对象的可复制特性

在Javascript中,对象其实就是一个key-value的array。但是出于节约资源的目的,几乎所有的现代语言,在出现以下代码的场景时候,都会采用引用传递,而并不是复制。 objectB=objectA; 对于诸如想C#之类的语言,你需要依靠专门的函数去完成clone的功能。但是Javascript却可以更简便的实现,关键利用的就是其Key-Value的array的特性。 在JavaScript中,对于普通基本类型变量的复制,是采用值传递的,这个和其他很多语言的机制也是相同的。 例如,以下代码。 var a=3,b=2; b=a;//b=3 b=4;//a=3 从上面代码,我们很明显可以看出是真正的复制。 因此,我们就很容易想到,既然JavaScript对象是key-value的array,那么如果我们把每个值取出来然后付给另一个对象是不是就ok了? 答案是肯定的。这里我写个简单的演示程序: var a={ property:"property", },b={}; //假复制 b=a;//复制,引用传递 b.property="change";//a.property值也为"change"了。 //真复制。 var c={}; a.property="back"; for(var item in a){ if(a.hasOwnProperty(item)){ c[item]=a[item]; } } c.property="changeagain";//a.property还是为back 在这里要注意的是,我们这里的c对象,不能用b对象代替,因为之前b对象已经被引用指向了a。你现在仍和改动,他默认都是会指向a的,所以如果你用b对象的话,会发现,什么都没有变。 SyntaxHighlighter.defaults['class-name'] = ”; SyntaxHighlighter.defaults['smart-tabs'] = true; SyntaxHighlighter.defaults['tab-size'] …

继续阅读 »

650 查看

javascript实现继承的方法

  如何像C#,php那样在javascript中设计那种,可以继承的库呢? 带着这个问题,先看一段代码(前提架设你对prototype的工作原理是了解的。不了解的话请参看我的另一篇文章,面向对象的Javascript和Prototype的理解) 1 function Testbase() 2 { 3 this.namealias="testbasename"; 4 this.at=function(){alert("tttt");} 5 } 6 7 function Subtestone() 8 { 9 //加入一些特有的属性和方法 10 this.subtest="one"; 11 } 12 13 function Subtesttwo() 14 { 15 //加入一些特有的属性和方法 16 this.subtest="two"; 17 } 18 19 …

继续阅读 »

1,281 查看

面向对象的Javascript和Prototype的理解

JavaScript是一个函数式语言。在其中并没有class的概念。这个时候你可能会有疑问,没有class的概念又怎么实现面向对象的呢? 在JavaScript中式基于prototype的,中文意思是原型。在这里prototype更类似与c#或php中继承的作用。具体怎么理解看代码 这里我以php语言为比较对象 首先看JavaScript代码 //基函数,这里的原型不是prototype,只是基类的感觉 //这里使用namealias,是因为function自己有name属性,这里就是Foo function Foo(){ this.namealias="Fooooo"; alert("constructor script"); this.doFoo=function(){ alert("doFoo"); } } //调用基函数中的方法,会提示Foo.doFoo不是一个函数 //Foo.doFoo(); //扩展基函数的方法 Foo.prototype.extendmethod=function() { alert("extend method"); } //调用扩展方法 //此时如果使用Foo.extendmethod()方法调用的话,会找不到, //这个很容易理解,基函数中是没有的, //而在prototype中的只有在new的时候才会传给new出来的对象。 var fooObj=new Foo(); fooObj.extendmethod();//成功运行 fooObj.doFoo();//这里是可以运行基函数中的方法的。 Foo.prototype.constructor(); 看了之后,你肯定你肯定会奇怪。其实只是没有搞清楚JavaScript中三个重要的角色,他们分别是 Object:对象,拥有且可以调用属性和方法。 Funtion:函数,拥有属性和方法,但不能调用,因为JavaScript认为Function是顺序执行的语句没有定义的部分。只有转为object才可以正确辨识。 Prototype:原型(实例),这个的概念,其实和Object有很大关系。Prototype外在表现不是一个Object,只是通过Prototype定义的东西,都会被new出来的Object访问到。因此,Prototype就常被用作扩展基函数(也可以认为是基类)的重要方法。但不是唯一,因为JavaScript本身也是支持对象动态增加属性和方法。只是Prototype在使用时,语意更明确,并且有具有construct()函数(Foo.prototype.construct();无需定义直接执行,代表执行基函数,基函数,其实也可以认为是中构造函数。) 但也一般情况只有Object可以调用prototype,函数只可以定义prototype,而无法调用。因为Object是没有prototype属性的,只有function有。但是对于function来说,他又看不到prototype中定义的东西,只有object可以。这么做的目的其实就是为了更好的语意!!当然万事皆有特殊,这里也有特殊。相信你前面就注意到了Foo.prototype.construct();,这里用的Foo,是Function。对的没有错,这个表示执行Foo中的函数的内容。这个construtor是在function中的prototype中可以看到的函数,同样也可以让Object看到(foo.constructor();)。这里关键要记住这个是个特例。 接下来附上一张图,能够很好,更清晰的理解上述所说 接下来我们来看看,相同功能和结构的PHP代码是如何实现的吧。 …

继续阅读 »

506 查看

Javascript文件的工具

jslint:用于验证JavaScript代码质量 http://www.jslint.com/ jsmin:压缩工具,就是去除空格和解释 http://fmarcia.info/jsmin/test.html

无觅相关文章插件,快速提升流量