摘要: 旧问新引,去除重复字符串操作阅读全文
posted @ 2008-02-26 09:54 lzwlfw 阅读(246) 评论(1) 编辑
摘要: ie 下jquery 先清空内容在把原内容插入到其它地的问题阅读全文
posted @ 2011-10-26 17:13 lzwlfw 阅读(67) 评论(0) 编辑
转自:http://topic.csdn.net/u/20080716/11/2317d040-48e7-42da-822e-040b4c55b46d.html
SQL code
MS SQL Server查询优化方法 查询速度慢的原因很多,常见如下几种 1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2、I/O吞吐量小,形成了瓶颈效应。 3、没有创建计算列导致查询不优化。 4、内存不足 5、网络速度慢 6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8、sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。 9、返回了不必要的行和列 10、查询语句不好,没有优化 可以通过如下方法来优化查询 1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要. 2、纵向、横向分割表,减少表的尺寸(sp_spaceuse) 3、升级硬件 4、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段 5、提高网速; 6、扩大服务器的内存,Windows 2000和SQL server 2000能支持4-8G的内存。配置虚拟内存:虚拟内存大小应基于计算机上并发运行的服务进行配置。运行 Microsoft SQL Server? 2000 时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的 1.5 倍。如果另外安装了全文检索功能,并打算运行 Microsoft 搜索服务以便执行全文索引和查询,可考虑:将虚拟内存大小配置为至少是计算机中安装的物理内存的 3 倍。将 SQL Server max server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半)。 7、增加服务器CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。使用并行还是串行程是MsSQL自动评估选择的。单个任务分解成多个任务,就可以在处理器上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作UPDATE,INSERT, DELETE还不能并行处理。 8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like 'a%' 使用索引 like '%a' 不使用索引用 like '%a%' 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。 9、DB Server 和APPLication Server 分离;OLTP和OLAP分离 10、分布式分区视图可用于实现数据库服务器联合体。联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件'分区视图') a、在实现分区视图之前,必须先水平分区表 b、在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器上运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。 11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE. 设置自动收缩日志.对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。 在T-sql的写法上有很大的讲究,下面列出常见的要点:首先,DBMS处理查询计划的过程是这样的: 1、 查询语句的词法、语法检查 2、 将语句提交给DBMS的查询优化器 3、 优化器做代数优化和存取路径的优化 4、 由预编译模块生成查询规划 5、 然后在合适的时间提交给系统处理执行 6、 最后将执行结果返回给用户其次,看一下SQL SERVER的数据存放的结构:一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。 12、Commit和rollback的区别 Rollback:回滚所有的事物。 Commit:提交当前的事物. 没有必要在动态SQL里写事物,如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过程。 13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。 14、SQL的注释申明对执行没有任何影响 15、尽可能不使用光标,它占用大量的资源。如果需要row-by-row地执行,尽量采用非光标技术,如:在客户端循环,用临时表,Table变量,用子查询,用Case语句等等。游标可以按照它所支持的提取选项进行分类: 只进 必须按照从第一行到最后一行的顺序提取行。FETCH NEXT 是唯一允许的提取操作,也是默认方式。可滚动性 可以在游标中任何地方随机提取任意行。游标的技术在SQL2000下变得功能很强大,他的目的是支持循环。 有四个并发选项 READ_ONLY:不允许通过游标定位更新(Update),且在组成结果集的行中没有锁。 OPTIMISTIC WITH valueS:乐观并发控制是事务控制理论的一个标准部分。乐观并发控制用于这样的情形,即在打开游标及更新行的间隔中,只有很小的机会让第二个用户更新某一行。当某个游标以此选项打开时,没有锁控制其中的行,这将有助于最大化其处理能力。如果用户试图修改某一行,则此行的当前值会与最后一次提取此行时获取的值进行比较。如果任何值发生改变,则服务器就会知道其他人已更新了此行,并会返回一个错误。如果值是一样的,服务器就执行修改。 选择这个并发选项OPTIMISTIC WITH ROW VERSIONING:此乐观并发控制选项基于行版本控制。使用行版本控制,其中的表必须具有某种版本标识符,服务器可用它来确定该行在读入游标后是否有所更改。 在 SQL Server 中,这个性能由 timestamp 数据类型提供,它是一个二进制数字,表示数据库中更改的相对顺序。每个数据库都有一个全局当前时间戳值:@@DBTS。每次以任何方式更改带有 timestamp 列的行时,SQL Server 先在时间戳列中存储当前的 @@DBTS 值,然后增加 @@DBTS 的值。如果某 个表具有 timestamp 列,则时间戳会被记到行级。服务器就可以比较某行的当前时间戳值和上次提取时所存储的时间戳值,从而确定该行是否已更新。服务器不必比较所有列的值,只需比较 timestamp 列即可。如果应用程序对没有 timestamp 列的表要求基于行版本控制的乐观并发,则游标默认为基于数值的乐观并发控制。 SCROLL LOCKS 这个选项实现悲观并发控制。在悲观并发控制中,在把数据库的行读入游标结果集时,应用程序将试图锁定数据库行。在使用服务器游标时,将行读入游标时会在其上放置一个更新锁。如果在事务内打开游标,则该事务更新锁将一直保持到事务被提交或回滚;当提取下一行时,将除去游标锁。如果在事务外打开游标,则提取下一行时,锁就被丢弃。因此,每当用户需要完全的悲观并发控制时,游标都应在事务内打开。更新锁将阻止任何其它任务获取更新锁或排它锁,从而阻止其它任务更新该行。 然而,更新锁并不阻止共享锁,所以它不会阻止其它任务读取行,除非第二个任务也在要求带更新锁的读取。滚动锁根据在游标定义的 SELECT 语句中指定的锁提示,这些游标并发选项可以生成滚动锁。滚动锁在提取时在每行上获取,并保持到下次提取或者游标关闭,以先发生者为准。下次提取时,服务器为新提取中的行获取滚动锁,并释放上次提取中行的滚动锁。滚动锁独立于事务锁,并可以保持到一个提交或回滚操作之后。如果提交时关闭游标的选项为关,则 COMMIT 语句并不关闭任何打开的游标,而且滚动锁被保留到提交之后,以维护对所提取数据的隔离。所获取滚动锁的类型取决于游标并发选项和游标 SELECT 语句中的锁提示。 锁提示 只读 乐观数值 乐观行版本控制 锁定无提示 未锁定 未锁定 未锁定 更新 NOLOCK 未锁定 未锁定 未锁定 未锁定 HOLDLOCK 共享 共享 共享 更新 UPDLOCK 错误 更新 更新 更新 TABLOCKX 错误 未锁定 未锁定 更新其它 未锁定 未锁定 未锁定 更新 *指定 NOLOCK 提示将使指定了该提示的表在游标内是只读的。 16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引 17、注意UNion和UNion all 的区别。UNION all好 18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的 19、查询时不要返回不需要的行、列 20、用sp_configure 'query governor cost limit'或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。 SET LOCKTIME设置锁的时间
 
SQL code
21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行 22、在SQL2000以前,一般不要用如下的字句: "IS NULL", " <> ", "!=", "!> ", "! <", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'",因为他们不走索引全是表扫描。也不要在WHere字句中的列名加函数,如Convert,substring等,如果必须用函数的时候,创建计算列再创建索引来替代.还可以变通写法:WHERE SUBSTRING(firstname,1,1) = 'm'改为WHERE firstname like 'm%'(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。NOT IN会多次扫描表,使用EXISTS、NOT EXISTSIN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同的是IS NULL,“NOT", "NOT EXISTS", "NOT IN"能优化她,而” <> ”等还是不能优化,用不到索引。 23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。 24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN (‘男’,‘女’) 25、将需要查询的结果预先计算好放在表中,查询的时候再SELECT。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。 26MIN() 和 MAX()能使用到合适的索引 27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procedure.这样不仅维护工作小,编写程序质量高,并且执行的速度快。 28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌INsert来插入(不知JAVA是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值.存储过程就没有这些动作: 方法:Create procedure p_insert as insert into table(Fimage) values (@image), 在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。 29、Between在某些时候比IN速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。 select * from chineseresume where title in ('','') Select * from chineseresume where between '' and '' 是一样的。由于in会在比较多次,所以有时会慢些。 30、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源。他的创建同是实际表一样。 31、不要建没有作用的事物例如产生报表时,浪费资源。只有在必要使用事物时使用它。 32、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到联合索引,用UNION all执行的效率更高.多个OR的字句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。 33、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。我们看视图的本质:它是存放在服务器上的被优化好了的已经产生了查询规划的SQL。对单个表检索数据时,不要使用指向多个表的视图,直接从表检索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到干扰.为了加快视图的查询,MsSQL增加了视图索引的功能。 34、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。 SELECT top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in('JCNAD00329667','JCNAD132168','JCNAD00337748','JCNAD00338345','JCNAD00333138','JCNAD00303570', 'JCNAD00303569','JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933','JCNAD00254567', 'JCNAD00254585','JCNAD00254608','JCNAD00254607','JCNAD00258524','JCNAD00332133','JCNAD00268618', 'JCNAD00279196','JCNAD00268613') order by postdate desc 35、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数 36、当用SELECT INTO时,它会锁住系统表(sysobjects,sysindexes等等),阻塞其他的连接的存取。创建临时表时用显示申明语句,而不是 select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = 'XYZ' --commit 在另一个连接中SELECT * from sysobjects可以看到 SELECT INTO 会锁住系统表,Create table 也会锁系统表(不管是临时表还是系统表)。所以千万不要在事物内使用它!!!这样的话如果是经常要用的临时表请使用实表,或者临时表变量。 37、一般在GROUP BY 个HAVING字句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作。他们的执行顺序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行,Having字句用来剔除多余的分组。这样Group By 个Having的开销小,查询快.对于大的数据行进行分组和Having十分消耗资源。如果Group BY的目的不包括计算,只是分组,那么用Distinct更快 38、一次更新多条记录比分多次更新每次一条快,就是说批处理好 39、少用临时表,尽量用结果集和Table类性的变量来代替它,Table 类型的变量比临时表好 40、在SQL2000下,计算字段是可以索引的,需要满足的条件如下: a、计算字段的表达是确定的 b、不能用在TEXT,Ntext,Image数据类型 c、必须配制如下选项 ANSI_NULLS = ON, ANSI_PADDINGS = ON, ……. 41、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的 SQL语句,是控制流语言的集合,速度当然快。反复执行的动态SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb中。以前由于SQL SERVER对复杂的数学计算不支持,所以不得不将这个工作放在其他的层上而增加网络的开销。SQL2000支持UDFs,现在支持复杂的数学计算,函数的返回值不要太大,这样的开销很大。用户自定义函数象光标一样执行的消耗大量的资源,如果返回大的结果采用存储过程 42、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快 43SELECT COUNT(*)的效率教低,尽量变通他的写法,而EXISTS快.同时请注意区别: select count(Field of null) from Tableselect count(Field of NOT null) from Table 的返回值是不同的。 44、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;否则使用 配制线程数量 <最大连接数启用SQL SERVER的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。 45、按照一定的次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发现 46、通过SQL Server Performance Monitor监视相应硬件的负载 Memory: Page Faults / sec计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。 Process: 1% DPC Time 指在范例间隔期间处理器用在缓延程序调用(DPC)接收和提供服务的百分比。(DPC 正在运行的为比标准间隔优先权低的间隔)。 由于 DPC 是以特权模式执行的,DPC 时间的百分比为特权时间 百分比的一部分。这些时间单独计算并且不属于间隔计算总数的一部 分。这个总数显示了作为实例时间百分比的平均忙时。 2%Processor Time计数器 如果该参数值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。 3% Privileged Time 指非闲置处理器时间用于特权模式的百分比。(特权模式是为操作系统组件和操纵硬件驱动程序而设计的一种处理模式。它允许直接访问硬件和所有内存。另一种模式为用户模式,它是一种为应用程序、环境分系统和整数分系统设计的一种有限处理模式。操作系统将应用程序线程转换成特权模式以访问操作系统服务)。 特权时间的 % 包括为间断和 DPC 提供服务的时间。特权时间比率高可能是由于失败设备产生的大数量的间隔而引起的。这个计数器将平均忙时作为样本时间的一部分显示。 4% User Time表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。 Physical Disk: Curretn Disk Queue Length计数器该值应不超过磁盘数的1.5~2倍。要提高性能,可增加磁盘。 SQLServer:Cache Hit Ratio计数器该值越高越好。如果持续低于80%,应考虑增加内存。 注意该参数值是从SQL Server启动后,就一直累加记数,所以运行经过一段时间后,该值将不能反映系统当前值。 47、分析select emp_name form employee where salary > 3000 在此语句中若salary是Float类型的,则优化器对其进行优化为Convert(float,3000),因为3000是个整数,我们应在编程时使用3000.0而不要等运行时让DBMS进行转化。同样字符和整型数据的转换。
posted @ 2011-05-12 13:48 lzwlfw 阅读(31) 评论(0) 编辑

主要是OperationContract要加Action=“Namespace+方法名”参数

Namespace是和对方的webservice 的Namespace相同

[ServiceContract(Namespace = "http://abc.org/")]
    [XmlSerializerFormatAttribute]
    
public interface IGameServer
    {
        [OperationContract(Action 
= "http://abc.org/GetGameList")]
        List
<GameInfo> GetGameList();
     }

 主要是XmlSerializerFormatAttribute属性

 

本地DataContract映射到对方

主要是通过DataContract 和DataMember 的Name属性

 

[DataContract(Namespace="http://abc.org/")]
    
public partial class GameInfo {
        
        
#region   Id
        
private Int32 m_id;        
        
/// <summary>  </summary>
        
/// 
        [XmlElement(ElementName="GameID")]
        
public Int32 Id {
            
get { return m_id; }
            
set { m_id = value;}        
        }        
        
#endregion        
        
#region   Name
        
private String m_name;        
        
/// <summary>  </summary>
        
/// 

        [DataMember(Name
="GameName")]
        
public String Name {
            
get { return m_name; }
            
set { m_name = value;}        
        }        
        
#endregion        
        
#region   Note
        
private String m_note;        
        
/// <summary>  </summary>
        public String Note {
            
get { return m_note; }
            
set { m_note = value;}        
        }        
        
#endregion        

    }
posted @ 2011-04-07 09:57 lzwlfw 阅读(73) 评论(0) 编辑
引用地址:http://www.w3cgroup.com/article.asp?id=293

ECMA262深入浅出

ECMA-262简述

ECMAScript语言概述

ECMAScript对象概述(原型链Prototype Chain)

ECMA-262主要术语

ECMAScript执行环境(作用域链Scope Chain,闭包机制)

ECMAScript函数(new原理)

ECMAScript内部属性(参考)

ECMAScript执行环境作用域链图示

ECMA-262参考资料

 
ECMA-262简述
 
ECMA(European Computer Manufacturers Association)
 
ECMA-262标准的最初的版本是基于Brendan Eich创造的JavaScript语言来制定的,它是ECMAScript脚本语言的规范及标准。该标准在1998年4 月通过快速通道提交到ISO/IEC JTC 1并被采纳为国际标准ISO/IEC 16262,所以之后一直简称为ECMA-262,该标准发展到现在已经到了第5版。


所有遵循ECMA-262标准实现的脚本都可以称之为ECMAScript,如JavaScript, JScript, ActionScript等等。
 
注意:ECMA-262是从ECMAScript脚本引擎实现的角度去描述的。
 
我们目前所使用的大部分浏览器中的脚本引擎多数都是基于ECMA-262标准第3版的实现,参见下图:
 
 ECMA262 3rd edition实现引擎列表
 
ECMAScript语言概述
 
ECMAScript最初的设计是一种网页脚本语言。

 
脚本语言是一种编程语言,可用来操作、自定义、自动化现有系统中的设备。
在某些系统中,一些可用的功能是可以通过用户接口来使用的。而脚本语言,就是将这些功能暴露给编程人员进行控制的机制。这样的系统,我们可以 说,它们为我们提供了一个运行脚本语言的宿主环境。脚本语言是专门给专业和非专业的编程人员使用的,为了适应非专业的程序员,有些方面多少有些不太严格。

脚本语言与宿主环境是两个不同的主体,比如,浏览器就为ECMAScript提供了一个宿主环境,BOM和DOM则都是浏览器提供的功能,而各种基于 ECMA262实现的脚本语言,如JavaScript,Jscript等,都可以为我们提供对BOM和DOM的操作方法。因为宿主环境的不同,它们提供 的功能也不尽相同,这也是我们知道的,不同的浏览器中会有不同的BOM和DOM的属性和方法。
 
 
ECMAScript是基于对象(object-based)的编程语言,在宿主环境中执行计算或操作对象。ECMAScript程序就是一个 对象间交互通信的聚合。 在ECMAScript中,“对象”(object)的properties是一个无序的集合,properties 是一个容器,可以包含其他的对象,原始值(primitive values)或方法(methods)。

原始值属于下列“内置类型”(built-in types)中的一员:Undefined, Null, Boolean, Number和String,“对象 ”则是内置类型:Object,“方法”是一个透过property关联到对象的函数。

 
ECMAScript定义了“内置对象”(built-in objects),以使ECMAScript实体更为完善。这些内置对象包括:Global对象,Object对象, Function对象,Array对象,String对象,Boolean对象,Number对象,Math对象,Date对象, RegExp对象和错误对象: Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError。

 
ECMAScript还定义了“内置操作符”或者说是“函数”或“方法”。ECMAScript操作符包括了各种一元运算符、乘除运算符、加减法运算符、位移运算符、关系运算符、相等运算符、二元运算符、二元逻辑运算符、分配运算符和逗号运算符。

 
ECMAScript的语法类似Java的语法。ECMAScript语法宽松是为了使它能够成为更容易使用的脚本语言。比如,变量不需要申明类型也不需要为properties指定类型,函数定义也可以不需要出现在它们的调用语句之前。
 
ECMAScript对象概述
 
ECMAScript没有像C++,Smalltalk,Java等语言中的真正的类,但是它支持构造器(constructors)。它在代 码执行时创建对象,为对象分配内存并初始化它们全部或部分初始值和properties。所有的构造器都是对象,但不是所有对象都是构造器。每个构造器都 有一个Prototype属性用于实现基于原型的继承(prototype-based inheritance)和属性共享(shared properties)。
 
对象在对构造器使用new表达式时被创建,比如,new String(“A String”)创建了一个新的字符串对象。不用new表达式直接去调用一个构造器,其结果将依赖于这个构造器的具体实现,如,String("A String") 产生一个原始值String,而不是一个对象。

 
ECMAScript支持基于原型的继承。所有构造器都有一个相关联的原型,所有由构造器创建的对象都隐含一个指向到该原型的引用(称为对象原 型),此外,一个原型可能有一个非空的、隐含的引用,指向到它的原型,所以,这又被称为是:原型链(prototype chain)
 
ECMAScript Prototype Chain原型链
 
当一个引用来自一个对象时,它会去该对象和它的原型(链)中查找与该property同名的属性,换句话说,会先直接从该对象中检测是否存在这个同名的引用,如果有则返回,否则再从该对象的原型(链)中去检测是否存在该引用。(DEMO)
 
DEMO:
<script type="text/javascript">
Object.prototype.hi = function(){
    alert('object.prototype.hi');
};
Object.prototype.greetings = function(){
    alert('object.prototype.greetings');
};
 
Function.prototype.greetings = function(){
    alert('function.prototype.greetings');
};
 
var CF = function(){};
CF.prototype.hello = function(){
    alert('CF.prototype.hello');
};
CF.prototype.bye = function(){
    alert('CF.prototype.bye');
};
 
var o = new CF();
o.hello = function(){alert('o.hello');};
 
o.hello();
o.bye();
o.hi();
o.greetings();
 
CF.hi();
CF.greetings();
</script>
 

在基于类的面向对象语言里,通常,状态由实例持有,方法由类持有,继承只有结构和行为。在ECMAScript中,状态和方法由对象持有,结构、行为和状态都可以被继承。
 
对象通常都不会直接包含那些由原型包含共享的属性和值。描述见下图:
 
 ECMAScript prototype原型
 
CF是一个构造函数(同时也是一个对象)。通过对它进行new表达式创建了5个实例对象:cf1,cf2,cf3,cf4,cf5。每个实例对象都包含有q1 和q2两个属性。(DEMO)

例如,Cfp是cf3的原型(虚线,表示隐含的原型关系),构造函数CF自己有两个属性P1和P2,它们对 Cfp,cf1,cf2,cf3,cf4,cf5都不可见。Cfp的属性CFP1对cf1,cf2,cf3,cf4,cf5可见(但不包括CF),还有那 些在Cfp的隐含的原型链中找到的 property name(非q1,q2或者CFP1的其他属性)。注意,CF和Cfp之间并非隐含的原型联系。
与基于类的对象语言不同,ECMAScript对象的属性可以通过给对象赋值的方式动态地添加到对象上,意思就是,构造函数不需要一个个地为那 些由它构造出的对象赋值,如上图,只要为CFp添加一个属性值,即可使得由CF构造出的所有对象:cf1,cf2,cf3,cf4,cf5共享。
 
DEMO:
<script type="text/javascript">
var CF = function(){};
CF.p1 = 'p1';
CF.p2 = 'p2';
 
CF.prototype = {CFP1:'cfp1'};
 
var cf1 = new CF(),cf2 = new CF(),cf3 = new CF(),cf4 = new CF(),cf5 = new CF();
 
alert(cf1.p1+','+cf2.p2);//构造函数自身的属性对由它构造出的对象不可见
 
alert(CF.CFP1);//对CF不可见
alert(cf1.CFP1);//对CF构造的所有对象可见
 
cf3.__proto__.CFP2 = 'cfp2';//在构造函数原型上添加属性
//__proto__相当于从cf3到CF.prototype的隐含的原型关系,该属性是SpiderMonkey引擎的私有属性,仅限在SpiderMonkey引擎中访问
 
alert(cf1.CFP2);//即可对所有该构造函数构造的对象进行共享
</script>
 
ECMA-262主要术语
 
以下是ECMAScript中主要术语的非正式定义。
 
Type
数据值的集合
Primitive Value
原始值包括Undefined,Null,Boolean,Number,String这些类型成员。原始值是语言实现中底层可以直接表示的数据。
Object
每个对象都是Object类型的成员。它包含的所有属性成员,如原始值、对象或者函数,是一个无序的集合。对象属性成员放置的函数又被称为方法。
Constructor
构造器是一个函数对象,用来创建和初始化对象。每个构造器都有一个关联的原型对象用来实现属性成员的继承和共享。
 
Prototype
ECMAScript中的原型用来实现对象结构、状态和行为的继承。当一个构造器构造了一个对象,这个对象会隐含地引用到该构造器关联的原型去解析属性的 引用。构造器关联的原型可以通过程序表达式constructor.prototype 来引用。在某个共享对象的原型上添加的属性值,通过继承,可以被所有其他对象共享。
Native Object
原生对象是由ECMAScript的实现提供的,独立于宿主环境。有些原生对像同时又是内置对象,其他的则可能会在执行一个 ECMAScript程序时产生。
Built-in Object
内置对象是由ECMAScript的实现提供的,独立于宿主环境,它们出现在ECMAScript程序开始执行的时候。所有的内置对象都是原生对象。
Host Object
宿主对象由为ECMAScript提供完整执行环境的宿主环境提供的。任何对象,不是原生对象,就是宿主对象。
 
Undefined Value
Undefined值是一个原始值,当一个变量没有被分配值的时候使用。
Undefined Type
Undefined类型只有一个值,undefined。
Null Value
Null值是一个原始值,它表示空的,没有的,或不存在的引用。
Null Type
Null类型有一个值,null。
Boolean Value
Boolean值是Boolean类型的成员,它只能是两个值中的一个,true或false。
Boolean Type
Boolean类型表示一个逻辑实体,由两个唯一值组成,一个是true,另一个是false。
 
Boolean Object
Boolean对象是Object类型的成员,它是内置对象Boolean的实例。意思是,一个Boolean对象是通过Boolean构造器的 new表 达式创建,提供一个boolean参数。结果对象有一个隐含的(未命名)原型boolean。一个Boolean对象支配一个 Boolean值。
String Value
String值是String类型的成员,它是一个有限的有序的,0到16位无符号整数长度的值。注意:尽管每个值通常都表示一个单独的16位的UTF-16文本的单元,但该语言不会做出任何限制和要求当这个值不是16位无符号整数的情况时。
String Type
String类型是所有字符串值的集合。
String Object
String对象是Object类型的成员,它是内置对象String的实例。
 
Number Value
Number值是Number类型的成员,它是一个直接表示的数字。
Number Type
Number类型是表示数字的值的集合。在ECMAScript中,该集合表示IEEE754的64位双精度运算格式的值,包含一个特殊值"Not-a- Number"(NaN),正无穷大和负无穷大。
Number Object
Number对象是Object类型的成员,它是内置对象Number的实例。
Infinity
原始值Infinity表示一个正无穷大的数字,Number类型成员。
NaN
原始值NaN表示IEEE标准"Not-a-Number"值的集合,Number类型成员。
 
ECMAScript执行环境
 
什么是执行环境?

想象一下,假设你就是一个ECMAScript引擎。

当你接收到一条语句:

this.x = y;

你能确定该做什么吗?

很明显, 我们不知道该做些什么,因为我们既不知道this是什么,也不清楚y是什么。

所以,如果要正确执行这条语句,我们需要一个上下文,用以确定this和y到底是什么,这个上下文,就是执行环境。
 
执行环境

当控制器转到ECMAScript可执行代码时,即会进入到一个执行环境中。活动的执行环境会在逻辑上形成一个堆栈,在这个堆栈的顶端存放的是运行时的执行环境。
 
函数对象(两种类型)
通过在源文件中透过函数声明、函数表达式或内置Function对象来定义的函数对象。
内部函数对象,它们属于内置对象,如parseInt, Math.exp等等。
 
可执行代码 (三种ECMAScript可执行代码类型)
Global代码
Eval代码
Function代码
 
变量实例

每个执行环境都会与一个“变量对象”关联。在源文件中定义的的变量和函数都会作为properties添加到该对象中去。例如函数的代码,参数将作为properties添加到该函数执行环境的变量对象中去。
 
 
在进入一个执行环境时,“变量对象”绑定properties的顺序如下:(DEMO)

针对函数代码:为每一个在参数列表中定义的形参,创建一个同名的标识符作为property添加到“变量对象”中,其 值由调用[[call]]时以参数的形式提供。如果调用者提供的参数值少于形参数量,其他的形参值将为undefined。如果遇到多个同名的形参,最后 一个同名形参的值将被保留,如果这最后一个形参也未被提供值,同样会是undefined。

针对函数声明:在“变量对象”中创建一个以它们的名字作为标识符的property,其值为创建后的函数对象。如果“变量对象”中已经有一个同名的property,则将它替换掉。

针对变量声明:在“变量对象”中创建一个以它们的名字作为标识符的property,其值为undefined,如果之前已有这个property,则其值不变。
 
DEMO:
<script type="text/javascript">
/*-------------函数代码------------*/
function x(a,a,b){alert(a);alert(b);};
x(1,2,3);
x(1);
/*-------------函数声明------------*/
function a(){alert(1);};
alert(a);
function a(){alert(2)};
alert(a);
/*-------------变量声明------------*/
var b;
alert(b); //其值为undefined
</script>
 
 
作用域链与标识符查找

所有的执行环境都与一个作用域链(scope chain)相关联。作用域链是一个用来查找标识符的对象列表。当控制器进入到一个执行环境中的时候,作用域链被创建并放置了一个初始的对象集合。在一个 执行环境运行的时候,它的作用域链只受with语句和catch子句影响。在执行的时候,标识符查找的方法如下:

1. 获取Scope Chain的下一个对象。如果没有对象了,则转到第5步
2. 调用Result(1)的[[HasProperty]]方法, 传递Identifier作为参数 
3. 如果Result(2)是true, 则返回一个Reference(引用)类型的值,它的base object是Result(1),而它的property name是Identifier
4. 跳到第1步
5. 返回一个Reference类型,它的base object是null,它的property name是Identifier

标识符查找的结果通常是一个名字为标识符字符串的引用值。
 
 
全局对象(Global Object)

在控制器进入任何执行环境之前,会创建一个唯一的全局对象,初始化的全局对象包括以下属性:

内置对象,如 Math,String,Date,parseInt等等,它们都是不可枚举的(DontEnum)。

宿主属性,它自己可能会包含一个值为全局对象的属性,比如,在HTML 的DOM中,全局对象中的window属性,就是全局对象自己。

当控制器进入了执行环境,ECMAScript运行的时候,全局对象可能还会被添加上一些额外的属性,一些之前已有的属性也有可能被改变。
 
This

所有活动的执行环境都会有一个this值,它依赖并取决于代码执行时的caller。

同一个执行环境中的this值是不变的。
 
 
Arguments对象

当控制器进入到一个函数的执行环境中时,会创建一个arguments对象,初始过程如下:

arguments对象的内部属性[[prototype]],是原生对象prototype,初始值是Object.prototype

创建callee属性,不可枚举(DontEnum),其值为正在执行的函数对象,这使得匿名函数也可以进行递归。

创建length属性,不可枚举(DontEnum),其值为caller提供的实际参数数量。

按少于length的正整数数量创建ToString(arg)属性,不可枚举(DontEnum),第一个实际参数值对应为arg = 0,第二个对应为arg = 1,依此类推。当实际参数少于形参时,该属性会在活动对象中相应地共享它的值。意思就是说,改变此属性将改变活动对象中的属性值,反之亦然。
 
 
进入一个执行环境时发生的那些事儿

每次调用函数或构造器都会进入一个新的执行环境,即使在一个函数递归地调用自己的时候亦是如此。每次return,都会退出这个执行环境。一个未捕捉的异常也可能退出一个或多个执行环境。

当控制器进入到一个执行环境中时,作用域链即被创建和初始化,变量实例化也开始进行,this值也被确定下来。
 
Global代码

作用域链创建并初始,仅包含global对象。

变量实例化进行的时候以global对象作为变量对象,属性为不可删除(DontDelete) 。

This值为global对象。

Eval代码

当控制器进入到eval代码的执行环境中时,先前活动的执行环境,引用到调用环境*,用来决定作用域链,变量对象和this值。如果没有调用环境,则所有这些都以全局代码形式进行处理。

作用域链初始化时包含一个与调用环境相同的对象,并保持相同的顺序。这包含了通过with语句和catch子句添加到调用环境作用域链上的对象。

变量实例化时使用调用环境下的变量对象。

This值与调用环境下的this值一致。

* 调用函数语句执行时的execution context就是calling context

Function代码

作用域链初始化时先添加活动对象,然后再添加该函数对象[[Scope]]属性中存储的其他对象。* 闭包机制

变量实例化执行时使用活动对象作为变量对象,属性为不可删除(DontDelete)。

This的值为Caller,如果caller不是对象(或者是null),则this值为global对象。
 
 
With语句

with语句会在当前执行环境中的作用域链顶端添加一个计算对象,在这个扩展的作用域链执行完语句之后,随机复原之前的作用域链。

With(表达式)语句的执行过程如下:

1.评估表达式
2.调用GetValue(Result(1))
3.调用ToObject(Result(2))
4.将Result(3)添加到 作用域链的顶端
5.用第4步扩展的作用域链来评估语句
6.使C=Result(5),如果在第5步时有异常抛出,则C=(throw,V,empty),V是这个异常(执行现在当作没有异常抛出继续进行)
7.在作用域链中移除Result(3)
8.返回C

注意:当控制器离开该“嵌入”的语句时,无论是正常还是异常,作用域链都将被恢复。
 
 
Catch子句

catch(标识符)块的执行过程如下:

1.使C为通过catch传递进来的参数
2.像new Object()一样创建一个新的对象
3.在Result(2) 的那个对象上创建一个property,名字是标识符,值是C,不可删除
4.将Result(2)添加到作用域链的顶端
5.评估这个块语句
6.将Result(2) 从作用域链中移除
7.返回Result(5)
 
函数声明

function Identifier(FormalParameterList opt){FunctionBody}

函数声明的解析过程如下:

1.创建一个new Function对象, FormalParameterList指定参数,FunctionBody指定函数体。将当前正在运行的执行环境中的作用域链作为它的作用域。

2.为当前的变量对象 创建一个名为Identifier的属性,值为Result(1)。
 
 
匿名函数表达式

function(FormalParameterList opt){FunctionBody}

匿名函数表达式的解析过程如下:

1.创建一个new Function对象, FormalParameterList指定参数,FunctionBody指定函数体。将当前正在运行的执行环境中的作用域链作为它的作用域。

2.返回Result(1)。
 
具名函数表达式

function Identifier(FormalParameterList opt){FunctionBody}

具名函数表达式的解析过程如下:

1.创建一个new Object对象
2.将Result(1)添加到作用域链的顶端
3.创建一个new Function对象,FormalParameterList指定参数,FunctionBody指定函数体。将当前正在运行的执行环境中的作用域链作为它的作用域。
4.为Result(1)创建一个名为Identifier的属性,其值为Result(3),只读,不可删除
5.从作用域链中移除Result(1)
6.返回Result(3)
 
创建函数对象

函数对象构造过程如下:

1.如果已有对象E,它已有FunctionBody,且与现在给到的FunctionBody相等,则跳转到第13步
2. 创建一个新的ECMAScript native对象F
3.设置F的[[Class]]为“Function”
4.设置F的[[Prototype]]为原始的Function prototype对象
5.设 置F的[[Call]](参见之后的Slide)
6.设置F的[[Construct]](参见之后的Slide)
7.设置F的[[Scope]]为一个新的作用域链,它和当前作用域包含相同的对象
8.设置F的lengeh属性值为形参数量,如果未定义参数,则为0。9.以new Object()表达式方式创建一个新的对象
10.设置F的 constructor属性值为Result(9)
11.设置F的prototype属性值为Result(9)
12.返回F
13.酌情(由实现者决定)跳转到第2步或第14步
14.创建 一个新的ECMAScript native对象F,连接到 E,复制所有E和F的非内部属性*以使得它们与E和F的保持一致。
15.设置F的[[Class]]属性值为“ Function”
16.设置F的[[Prototype]]属性值为原始的Function prototype对象
17.设置F的[[Call]]属性
18.设置F的[[Construct]]属性
19. 设置F的[[Scope]]属性值为一个新的作用域链,它和当前作用域包含相同的对象
20.返回F

* 内部属性指的是所有以[[]]书写的属性
 
 
创建函数对象

注意:

每个function都会自动创建一个prototype属性,以使得它们可以当作构造器来使用。

第1步,使得类似函数A中嵌套了一个不依赖于A的函数B的这种情况进行优化。在这种情形的实现中,允许在A每次被调用的时候,重用B这个对象。

第13步决定是否执行此 优化。如果在某个实现中选择不,则会跳转到第2步。
 
 
创建函数对象

连接对象(很多引擎都未去做这个实现)

当两个或更多的Function对象连接时,它们具有如下特殊的行为:

1.任何时候,对 象O创建或设置一个非内部属性时,通信机制会立即在其他所有与O连接的对象上做相同的操作。

2.任何时候,对象O删除一个非内部属性, 通信机制会立即在其他所有与O连接的对象上做相同的操作。

3.如果对象O与P相连,它们可以通过==和===来进行比较。

4.当对象O与P相连 ,且对象P与Q相连,则O与Q也会自动相连。

注意:相连的对象除了它们各自不同的内部属性外,是很难进行区别的。而这些内部属性可能也只有[[Scope]]会不同。
 
调用函数对象

[[Call]]

当函数对象F调用了[[Call]]属性,将执行以下步骤:

1.将F的形参表、传递的参数列表,和this植入到一个新的执行环境

2.评估F的FunctionBody

3.退出在第1步植入的执行环境,恢复之前的执行环境

4.如果Result(2).type是 throw,抛出Result (2).value

5.如果Result(2).type是return,返回Result(2).value

6.Result(2).type默认情况下,返回undefined
 
 
new操作原理

[[Construct]]

当函数对象F调用了[[Construct]]属性,将执行以下步骤:

1.创建一个新的ECMAScript native对象
2.将 Result(1)的[[Class]]属性值设为“Object”
3.取得F的prototype属性值
4.如果Result(3)是一个对象,将Result(1)的[[Prototype]]属性值设置为Result(3)
5.如果Result(3)不是一个对象,将Result(1)的[[Prototype]]属性值设置为原始的Object prototype对象
6.调用F的 [[Call]]属性,将Result(1)设置为this值,将[[Construct]]传递的参数当作参数列表
7.如果Type(Result(6))是一个对象,返回Result(6)
8.返回Result(1)
 
DEMO:
<script type="text/javascript">
/*new操作原理(spiderMonkey引擎下测试)*/
 
var a = function(sA,sH){
    var x = "x";
    this.a = sA;
    this.h = sH;
    this.say = function(){alert(this.a+','+x)}
}
a.prototype.hi = function(){alert(this.h)}
 
var createInstance = function(source){
    var p = {}
    var args = Array.prototype.slice.call(arguments,1);
    p.__proto__ = source.prototype;
    source.apply(p,args);
    return p;
}
 
var A = createInstance(a,"A","hi A");
A.say();
A.hi();
</script>
 
ECMAScript内部属性
 
[[Prototype]]
This对象的原型,该属性值只会是一个object或null,所有的[[Prototype]] chain最终都都会通向到null。
[[Class]]
指明This对象类别的字符串值
[[Value]]
与This对象关联的内部状态信息
[[Get]](PropertyName)
返回指定属性的值
[[Put]](PropertyName Value)
设置指定的属性值
[[CanPut]](PropertyName)
返回是否可以执行[[Put]]指定属性的操作的Boolean值
[[HasProperty]](PropertyName)
返回对象是否存在指定的属性名的Boolean值
[[Delete]](PropertyName)
移除对象指定的属性
[[DefaultValue]](Hint)
返回对象的默认值,只能是原始值,不允许对象和引用。
[[Construct]] a list of argument values provied by the caller
通过调用new操作符构造一个对象。
[[Call]] a list of argument values provied by the caller
通过函数调用表达式执行与对象关联的代码。
[[HasInstance]](Value)
返回一个Boolean值,表示This对象是否存在指定的委派(实例),仅对ECMAScript native中的Function对象实现。
[[Scope]]
作用域链,用于表示一个函数对象执行时的环境。
[[Match]](String,Index)
为正则表达式匹配和返回一个MatchResult的值。
 
ECMAScript Execution Context and Scope Chain
 
ECMAScript Execution Context and Scope Chain
 
Scope Chain DEMO:
<script type="text/javascript">
var v = 'global';
 
var x = function(v){
 alert(v);
 with({}){
    v = 'w';
 }
 try{alert(me);}catch(e){}
};
 
var y = function(){
 alert(v);
};
 
var z = function(){
 var v = 'z';
 y();
 alert(v);
};
 
var n = function(){
 var i = 0;
 var inner = function(){
    alert(++i);
 };
 return inner;
};
 
x();
 
z();
 
var fn = n();
 
fn();
</script>
 
 
ECMA-262参考资料
ECMA-262 3rd Edition
http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,% 20December%201999.pdf
 
ECMA-262 5th Edition
http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf
 
What is Ecma International
http://www.ecma-international.org/memento/index.html

 

 

 

 

 

posted @ 2011-03-02 11:24 lzwlfw 阅读(235) 评论(0) 编辑

引用的别人的奥

一、用set命令设置自定义变量
显示、设置或删除 cmd.exe 环境变量。
SET [variable=[string]]
   variable   指定环境变量名。
   string 指定要指派给变量的一系列字符串。
要显示当前环境变量,键入不带参数的 SET。
SET 命令不允许变量名含有等号。

例子:
@echo off
set var=我是值
echo %var%
pause
请看 set var=我是值 ,这就是BAT直接在批处理中设置变量的方法!
set 是命令 var是变量名   =号右边的"我是值"是变量的值
在批处理中我们要引用这个变就把var变量名用两个%(百分号)扩起来,如%var%

SET还可以提供一个交互界面,让用户自己输入变量的值,然后我们在来根据这个值来做相应操作,现在我就来说说SET的这种语法,只需要加一个"/P"参数就可以了!www.cmdos.net
SET /P variable=[promptString]

例子:
@echo off
set /p var=请输入变量的值:
echo 您输入了 %var%   ~_~
pause
set /p 是命令语法   var是变量名 =号右边的"请输入变量的值: ",这个是提示语,不是变量的值了!
运行后,我们在提示语后面直接输入1,就会显示一行您输入了 1 ~_~
好了,先回顾到这,现在讲SET其他功能
使用set /?查看SET的帮助我们发现SET除了我上面讲的
SET [variable=[string]]
SET /P variable=[promptString]
这两种语法外,还有如下几种语法:
SET /A expression
环境变量替换已如下增强:
%PATH:str1=str2%
%PATH:~10,5%
%PATH:~-10%
%PATH:~0,-2%
这机种语法有什么用处呢?下面我们来一个个讲解他们!
二、用set命令进行简单计算
语法:SET /A expression
/A 命令行开关指定等号右边的字符串为被评估的数字表达式。该表达式
评估器很简单并以递减的优先权顺序支持下列操作:
()                -分组
! ~ -             -一元运算符
* / %             -算数运算符
+ -                 -算数运算符
<< >>             -二进制逻辑移位
&                -二进制按位“与”
^                -二进制按位“异”
|                -二进制按位“或”
= *= /= %= += -= -算数赋值
&= ^= |= <<= >>= -二进制运算赋值
,                -表达式分隔符

上面这些是系统帮助里的内容,看着是不是有点晕,没关系我来简单解释一下:
set的/A参数就是让SET可以支持数学符号进行加减等一些数学运算!
现在开始举例子介绍这些数学符号的用法:
例:
@echo off
set /p input=请输入计算表达式:
set /a var=%input%
echo 计算结果:%input%=%var%
pause
上面的例子是龙卷风设计的,很好用哟,请看下面几个运算过程:
注意:DOS计算只能精确到整数
请输入计算表达式:1+9+20+30-10
计算结果:1+9+20+30-10=50
请按任意键继续. . .
请输入计算表达式:10/3
计算结果:10/3=3   #DOS计算精确到整数,小数舍了。
请按任意键继续. . .
请输入计算表达式:-100+62
计算结果:-100+62=-38
请按任意键继续. . .
请输入计算表达式:100%3 #求余数
计算结果:100%3=1
请按任意键继续. . .
请输入计算表达式:(25+75)*2/(15+5)
计算结果:(25+75)*2/(15+5)=10
请按任意键继续. . .
请输入计算表达式:1234567890*9876543210
无效数字。数字精确度限为 32 位。
计算结果:1234567890*9876543210=
请按任意键继续. . .
注意:上面的计算过程显示,DOS计算只能精确到32位,这个32位是指二进制32位,其中最高位为符号位(0为正,1为负),低位31位为数值。31个 1换成十进制为2147483647,所以DOS计算的有效值范围是-2147483647至2147483647,超出该数值范围时计算出错,请看下面 的计算过程:
请输入计算表达式:2147483647-1 #最大值减1,值有效
计算结果:2147483647-1=2147483646
请按任意键继续. . .

运行set /a a=1+1,b=2+1,c=3+1后会显示一个4,但我们用
echo %a% %b% %c%后看结果,会发现其他数学运算也有效果!,这就是"逗"号的
作用!

有时候我们需要直接在原变量进行加减操作就可以用这种语法
set /a var+=1   这样的语法对应原始语法就是set /a var = %var% + 1
都是一样的结果,在原变量的值上在进行数学运算,不过这样写简单一点
再来一个:
set /a var*=2
其他都这么用,只要帮助里有这个语法!

另外还有一些用逻辑或取余操作符,这些符号,按照上面的使用方法会报错的
比如我们在CMD里输入set /a var=1 & 1 "与运算",他并不会显示为1,而是报错,
为什么?对于这样的"逻辑或取余操作符",我们需要把他们用双引号引起来,也可以用转义字符^,看例子
set /a var= 1 "&" 1 这样结果就显示出来了,其他逻辑或取余操作符用法
set /a var= 1 "+" 1 异运算
set /a var= 1 "%" 1   取模运算
set /a var= 3 "<<" 2 左移位运算, 3的二进制为11,左移2位为1100,换成十进制就是12,自行验证
set /a var= 4 ">>" 2右移位运算,4的二进制为100,右移动2位为1,结果为1
还有几个数学不太行,搞不清楚了....不列出来了,
龙卷风补充:凡是按位计算均需换算成二进制,下面行中的符号均针对二进制
这些符号也可以用&= ^= |= <<= >>= 这样的简单用法如
set /a var"&=" 1 等于set /a var = %var% "&" 1 注意引号
思考题:求2的n次方
答案:
@echo off
set /p n=请输入2的几次方:
set /a num=1^<^<n
echo %num%
pause

三、用set命令进行字符串处理
1、字符串替换
好了,符号说到这,现在说%PATH:str1=str2%
上面语法的意思就是:将字符串变量%PATH%中的str1替换为str2
这个是替换变量值的内容,看例子
@echo off
set a= bbs. verybat. cn
echo 替换前的值: "%a%"
set var=%a: =%
echo 替换后的值: "%var%"
pause
运行显示:(龙卷风添加)
替换前的值: " bbs. verybat. cn"
替换后的值: "bbs.verybat.cn"
对比一下,我们发现他把变量%a%的空格给替换掉了,从这个例子,我们就可以发现
%PATH:str1=str2%这个操作就是把变量%PATH%的里的str1全部用str2替换
比如我们把上面的例子改成这样
@echo off
set a=bbs.verybat.cn
echo 替换前的值: "%a%"
set var=%a:.=伤脑筋%
echo 替换后的值: "%var%"
pause
运行显示:
替换前的值: "bbs.verybat.cn"
替换后的值: "bbs伤脑筋verybat伤脑筋cn"
解释set var=%a:.=伤脑筋%
set是命令 var是变量名 字a是要进行字符替换的变量的值,"."为要替换的值,
"伤脑筋"为替换后的值!
执行后就会把变量%a%里面的"."全部替换为"伤脑筋"
这就是set的替换字符的很好的功能! 替换功能先讲到这,下面将字符串截取功能
2、字符串截取
**********************************************
截取功能统一语法格式为:%a:~[m[,n]]%
**********************************************
方括号表示可选,%为变量标识符,a为变量名,不可少,冒号用于分隔变量名和说明部分,符号~可以简单理解为“偏移”即可,m为偏移量(缺省为0),n为截取长度(缺省为全部)

%PATH:~10,5%   这个什么意思,看例子:
截取功能例子1:
@echo off
set a=bbs.verybat.cn
set var=%a:~1,2%
echo %var%
pause
执行后,我们会发现只显示了"bs"两个字母,我们的变量%a%的值不是为bbs.verybat.cn吗?
怎么只显示了第2个字母和第3个字母"bs",分析一结果我们就可以很容易看出
%PATH:~10,5%就是显示变量PATH里从11位(偏移量10)开始的5个字符!
分析set var=%a:~1,2%
   set是命令,var是变量值,a要进行字符操作的变量,"1"从变量"a"第几位开始显示,"2"表示显示几位。
合起来就是把变量a的值从第2位(偏移量1)开始,把2个字符赋予给变量var
这样应该明白了吧~
其他两种语法
%PATH:~-10%
%PATH:~0,-2%
他们也是显示指定变量指定几位的值的意思
%PATH:~-10% 看例子
截取功能例子2:
@echo off
set a=bbs.verybat.cn
set var=%a:~-3%
echo %var%
pause
运行结果:.cn
这个就是把变量a倒数3位的值给变量VAR
当然我们也可以改成这样
截取功能例子3:
@echo off
set a=bbs.verybat.cn
set var=%a:~3%
echo %var%
pause
运行显示:.verybat.cn
这个就是把变量a的从第3位开始后面全部的值给变量VAR
%PATH:~0,-2%   例子
截取功能例子4:
@echo off
set a=bbs.verybat.cn
set var=%a:~0,-3%
echo %var%
pause
执行后,我们发现显示的是"bbs.verybat",少了".cn"
从结果分析,很容易分析出,这是把变量a的值从0位开始,
到倒数第三位之间的值全部赋予给var
如果改成这样
截取功能例子5:
@echo off
set a=bbs.verybat.cn
set var=%a:~2,-3%
echo %var%
pause
运行显示:s.verybat
那么他就是显示从第3位(偏移量2)开始减去倒数三位字符的值,并赋予给变量var
讲得好,例子就是说明问题,为便于记忆,龙卷风小节如下:
a=bbs.verybat.cn
%a:~1,2% =“bs” 偏移量1,从第二位开始向右取2位
%a:~-3% =“.cn”   偏移量负3,即倒数3位(也可理解为留下右边3位),右取全部
%a:~3%     =“.verybat.cn” 偏移量3(也可理解为去掉左边3位),右取全部
%a:~0,-3% =“bbs.verybat” 偏移量0,右取长度至负3,即倒数3位
%a:~2,-3% =“s.verybat”   偏移量2,右取长度至负3,即倒数3位
**********************************************
所以,截取功能统一语法格式为:%a:~[m[,n]]%
**********************************************
方括号表示可选,%a%为变量名,不可少,冒号用于分隔变量名和说明部分,符号~可以简单理解为“偏移”即可,m为偏移量(缺省为0),n为截取长度(缺省为全部)
上面所述用法其实相当于vbs函数mid、left、right
%a:~0,n%   相当于函数left(a,n)   取左边n位
%a:~-m%   相当于函数right(a,m) 取右边m位
%a:~m,n% 相当于函数mid(a,m+1,n) 从m+1位开始取n位
%a:~m,-n% 相当于函数mid(a,m+1,len(a)-m-n)
%a:~m %   相当于函数mid(a,m+1,len(a)-m) 或者right(a,len(a)-m)
思考题目:输入任意字符串,求字符串的长度
参考答案:
@echo off
set /p str=请输入任意长度的字符串:
echo 你输入了字符串:"%str%"
if not defined str (pause & goto :eof)
set num=0
:len
set /a num+=1
set str=%str:~0,-1%
if defined str goto len
echo 字符串长度为:%num%
pause

posted @ 2009-12-07 11:44 lzwlfw 阅读(844) 评论(0) 编辑
摘要: c#版 如:10!=1*2.....10 只有个位2*5和10的倍数可以产生0 所以10!后有2个0 同样推理20!后面有4个0. 所以得到公式 b=n%10如b>=5: n/10*2+1 反直则是n/10*2不知道对不对[代码]阅读全文
posted @ 2009-11-24 14:08 lzwlfw 阅读(189) 评论(0) 编辑
摘要: 引:http://www.javaeye.com/topic/180611在ie的内存泄露中跨页面的泄露是最严重的,浏览器刷新了仍然无法释放掉泄露占用的资源,造成访问速度越来越慢,内存占用越来越大 closure引起cross page leak的主要原因是closure和dom元素的互相引用 看这个例子: Java代码 <divid="bb"><divid="aa">...阅读全文
posted @ 2009-11-19 11:52 lzwlfw 阅读(153) 评论(0) 编辑
摘要: 引:http://www.cnblogs.com/Mainz/archive/2009/03/19/1416775.html 下面是从《javascript高级编程》中摘录的: 下载时间 Web浏览器下载的是JavaScript源码,也就是所有的长变量与注释都会包含在内。这个因素和其他因素都会增加下载时间,这会增加脚本运行的总时间。增加下载时间的关键因素就是脚本所包含的字节数。 要记住一个关键数...阅读全文
posted @ 2009-11-19 11:38 lzwlfw 阅读(63) 评论(0) 编辑
摘要: 以下引用来自于:http://hi.baidu.com/newperson/blog/item/379350f4e71483d1f3d3850e.html js获取浏览器高度和宽度值(多浏览器) 2009年06月01日 星期一 14:02 IE中: document.body.clientWidth ==> BODY对象宽度 document.body.clientHeight ==>...阅读全文
posted @ 2009-11-18 16:28 lzwlfw 阅读(167) 评论(2) 编辑
摘要: 直接看代码:[代码]用法:$(".class").numberable(); 这只是限制了数字,还可以扩展其他的功能,阅读全文
posted @ 2009-11-10 09:44 lzwlfw 阅读(248) 评论(0) 编辑