分类目录归档:web

JavaScript基本类型及类型转换

  每种语言都有自己的基本类型,JavaScript也不例外。在JavaScript中有五大基本类型,分别是number,string,boolean,null,undefined。其他不属于这五种基本类型的都是对象,有时候null也h是对象的一种。

  一、基本类型介绍

  可以通过typeof来确定是哪种类型。

  number包括基本的数字,Infinity,unInfinity,NaN。其中NaN比较特殊,在一个不能做运算的时候做了运算就会得到NaN的结果,例如1*’abc’。

  string几乎所有的语言都有的类型,但是实现都不一样。

  boolean也是很常见的一种基本类型,只有两个值true和false。

  null其实就是空

  undefined指的是未定义的

  二、类型转换

  任何语言都可以进行类型转换。javascript特殊的一点是她回自动做一些类型转换,这样做的好处是开发者不用做一些强制的类型转换,但是这个特性也是被视为javascript诟病之一,很多人认为这个特性会造成一些意想不到的错误。当然我觉得只要掌握好类型转换的特点和细节,就能够趋利避害。

  说几点在类型转换中容易出错的地方。

  在做+操作时一定要注意,因为在javascript中,+既可以是数字的加法,也可以是字符串的拼接。当两个操作数之一是字符串是就会将另一个数字转换为字符串,再做字符串的拼接,例如1+’12’和’1’+12得到的都是字符串’112’。所以如果想要做数字的加法,一定要保证两个操作数都是数字,可以用Number进行强制类型转换,例如1+Number(’12’)。当然也可以用一些简单地转换例如1+1*’12’。但是不推荐这二种做法,因为语义不明确,会给阅读代码的人造成困惑或误解。

  任何变量都可以转换为Boolean值,不是true就是false。常见的空字符串”,undefined,null,NaN,0都可以被转换为false。其他的则都是true。

  我们在定义变量时,经常会这么做var a = a || 10。我们想做的是,如果a被定义了则使用a的值,没定义则赋值为10.但是经常忽略,如果a的值为0。所以这种定义方法一定要慎用。

  在javascript中做等比较时有两种做法,一个是==另一个是===,对应的不等比较是!=和!==。===被称作是严格相等。两者的区别是,==会做类型转换而===不会,例如1==’1’,1==true都会返回true,而1===’1′,1===true则会返回false。所以在做等比较时也一定要慎重。

  三、总结

  作为一门弱类型语言,javascript的类型转换一方面给开发者带来了很多方便而受人们追捧,另一方面也会产生一些莫名其妙的错误而遭人谩骂。其实我觉得任何语言都是不完美的,而我们能做的就是真正精通这些可能产生误区的特性,趋利避害才是王道。

大话设计模式(带目录完整版) PDF+源代码  http://www.linuxidc.com/Linux/2014-08/105152.htm

JavaScript设计模式 中文清晰扫描版PDF  http://www.linuxidc.com/Linux/2015-09/122725.htm

js 閉包?

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>


New Document






 

不是js闭包。是由于js的变量作用域。js不同于c等语言,是从变量声明处开始。而是在整个作用域名中。

如下代码:

var g=”global”;

function test()

{

alert(g);//undefined

var g=”local”;//init

alert(g);//local

}

上述代码。等价于

var g=”global”;

function test()

{

var g;

alert(g);//undefined

g=”local”;//init

alert(g);//local

}

备记location.href

今天遇到个问题.

使用window.location.href 时

如果url是encode过的.

如window.location.href=”http%3A%2F%2Fmusic.sina.com.cn%2Fmycd%2Fceb%2Fnewcardinfo.php”

假设使用js的页面是http://test.html

会出现http://test.htmlhttp%3A%2F%2Fmusic.sina.com.cn%2Fmycd%2Fceb%2Fnewcardinfo.php

页面找不到.

总结.使用window.location.href时.如果值是一个完整的url .不应该做urlenocode.

怪异的js编码问题

页面是gb2312编码。

js文件也是gb2312编码。

在本地和一个服务器A上正常。

但是换到另一台服务器B上就会出现乱码现象。加上charset=”gb2312″也没有用。

直接在chrome/firefox浏览器中打开js文件。A正常。B乱码。

这说B服务器上的js文件虽然是gb2312编码。但是浏览器却认作utf8。估计是服务器配置相关。http://www.diybl.com/course/4_webprogram/php/phpjs/200863/121166.html

网js 编码 问题  

GBK的页面(不要问我为什么GBK,因为GBK,所以GBK),引用了Google map的API, 但是由于GoogleMap API返回的js脚本是utf-8的,所以导致在IE下, 浏览器无法正确解析.

这个问题,总的来说,可以用下图描述(原谅我的美术水平):

问题图

问题

也就是, 由于服务器中生成的HTML是基于gbk编码的, 并且由于Apache的DefaultCharset(后叙), 所以导致IE会以gbk编码去解析从外部引入的GoogleMap js,那肯定是不能正确解释的.

浏览器判断一个页面的编码有俩个途径, 一种是通过HTTP响应头,

HTTP/1.x 200 OKDate: Sat, 18 Oct 2008 21:53:51 GMTServer: Apache/2.0.52 (Red Hat)X-Powered-By: PHP/5.3.0alpha2Connection: closeTransfer-Encoding: chunkedContent-Type: text/html; charset=GB2312

注意最后一行, 这个是由HTTP头部指明的页面编码格式.
另外一种就是我们常见的, 也会另很多初学者困惑的meta:

风雪之隅

问题就在于,没有一个统一的标准,来指明这俩中方式的优先级, 不同的浏览器有着不同的优先级策略.这也就是为什么,我们在FF下正常浏览的页面,在IE下会乱码的原因.
我之前的文章Apache的Charset设置中已经介绍过了在Apache下设置DefaultCharset以后产生的影响,

这个问题已经遇到过俩次了,就是页面中明确指明了编码是UTF8,但是显示是乱码。
   虽然知道解决方法,也知道是Apache的原因,但是一直没有去找其所以然,今天趁机,就研究了一下。

   1.页面没有指定charset , Apache配置defaultcharst gbk , 页面文件编码是utf-8
          结果: 乱码,使用wireshark抓包,发现服务器返回的header中指明了:

Content-Type: text/html; charset=GBK

          结论:当页面没有指明charset的时候,Apache的defaultcharset起作用

   2. 页面指定charset为utf-8, Apache配置defaultcharset gbk. 页面文件是utf-8


        


        



         结果还是出现乱码。

         结论:当Apache配置了DefaultCharset, 将忽略页面的charset申明。

   3 PHP header申明charset为utf8, Apache配置defaultcharst gbk,页面文件编码是utf8

header(“Content-Type:text/html; charset=utf-8”);

        结果 : 页面显示正常。

   4 Apache设置DefaultCharset off

           结果,页面显示正常。

翻阅了下Apache2的手册:

AddDefaultCharset 指令
说明     当应答内容是text/plain或text/html时,在HTTP应答头中加入的默认字符集
语法     AddDefaultCharset On|Off|charset
默认值     AddDefaultCharset Off
作用域     server config, virtual host, directory, .htaccess
覆盖项     FileInfo
状态     核心(C)
模块     core

当且仅当应答内容是text/plain或text/html时,此指令将会在HTTP应答头中加入的默认字符集。理论上这将覆盖在文档体中通过标 签指定的字符集,但是实际的行为通常取决于用户浏览器的设置。AddDefaultCharset Off 将会禁用此功能。 AddDefaultCharset On 将启用Apache内部的默认字符集iso-8859-1 。您也可以指定使用在IANA注册过的字符集名字 中的另外一个charset 。比如说:

AddDefaultCharset utf-8

    

    也就是说,当Apache不指定defaultcharset的时候,页面编码由页面自己的meta标签指定。

    当Apache指定的时候,将忽略页面中的meta标签指定的编码. 但是容许脚本直接header编码方式给客户端

最后,还有一个问题没有得出结果:

     当Apache和页面都没有指定的时候, 又如何?

     我在自己的机器上,如果都不指定, 默认还是utf8

服务器端生成response内容以后, 如果脚本没有显示的调用header发送编码申明,那么Apache就会根据DefaultCharset生成响应HTTP头部的Content-type中的charset字段;
反之如果脚本显示申明了,那么就会按照脚本header申明中的charset设置.

这样到了浏览器端以后, 浏览器就可以根据HTTP头的charset申明来按照特定的编码格式解析获取到的HTML代码,但现在的问题是, 页面是GBK的,但是引用的外部js文件是utf8编码的,这样的情况, 我们可以使用一个script的属性来解决:

sidebartop Laruence

年二十有六,好追根究底,有不良嗜好, 幸性本善。

乙酉年识互联,丁亥年入雅虎, 翌年入百度。

虽性好安稳,然经变无数,唯常叹”人生,菠菜汤尔”。

sidebarbottomsidebartopCategoriessidebarbottomsidebartopFavorites

jquery uploadify的fileUploadSettings解决之道

最近用jquery的插件。uploadify.发现用fileUploadSettings无法改变参数。去网上看说这个功能还没有实现,估计再过几个星期才会实现。我这里提供我的一个替代方案。

执行$(‘#someid’).update_data(key,value);即可。

备注:只有FF 起了作用。

IE和chrome不行。对于IE和chrome估计要改flash源码才行了。可惜我不会as.只能等2.0了。

$.fn.extend({
update_data: function(key,value) {
if(typeof(value)==’object’){
   var scriptDataString = ”;
   for (var name in value) {
   scriptDataString += ‘&’ + name + ‘=’ + value[name];
   }
   value= escape(scriptDataString);
}
var obj=$(“#”+$(this).attr(“id”)+”Uploader”);
if($.browser.msie){
   obj = obj.find(“param[name=movie]”);
   obj.attr(“value”,url_replace(key,value,obj.attr(“value”)));
}
else{
   obj.attr(“src”,url_replace(key,value,obj.attr(“src”)));
}    
}
});

/*
**key要替换的参数名
**value替换后的参数值
**url,如果没有指定则为浏览器地址
*/
function url_replace(key,value,url){
if(arguments.length<2){
   alert(“param error”);
   return “param error”;
}
if(!url){
   var url=location.href;
}
url=url.replace(/#/,””);
if(request(key,url)!=””){
   reg = new RegExp(“(“+key+”=[^&]+)”,”ig”);
   return url.replace(reg,key+”=”+value);
}
else{
   var sep=url.indexOf(“?”)==-1?”?”:”&”;
   return url+sep+key+”=”+value;
}

}
/*
**获取 url 的参数值,不区分大小写,如无此参数,返回空字符串.
*/
function request(paras,url){
if(!url){
    var url = location.href;
}
var paraString = url.substring(url.indexOf(“?”)+1,url.length).split(“&”);
var paraObj = {} ;
for (i=0; j=paraString[i]; i++){
   paraObj[j.substring(0,j.indexOf(“=”)).toLowerCase()] = j.substring(j.indexOf(“=”)+1,j.length);
}
var returnValue = paraObj[paras.toLowerCase()];
if(typeof(returnValue)==”undefined”){
return “”;
}else{
return returnValue;
}
}

td position

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>


New Document



1 2 3 4 5 6 7 8 9




在IE8下前两个td确实会固定下来。

但是在FF下不会。

待解决。。。

setTimeout()。Js的伪多线程

首先为什么说setTimeout()是多线程。因为我在顺序执行流程的时候,我可以把一部分耗时间,但又不需要及时处理的代码放到setTimeout()中去执行。即空闲时间去执行。为什么说是空闲时间呢。可以写一个小dome测试一下。



#1那里耗了100ms.setTimeout()是50ms.如果是严格的50ms后执行应该在循环里就执行了。但实际结果是先执行的#2。

以下是执行结果。

687fininsh671

687-671=16.这说明。setTimeout()当时就开始计时了。当时间到了的时候并不是马上执行。而是看有没有其它操作。在确定没有其它操作后才真正的执行代码的。这样就可以把一些耗时间的操作放到空闲时处理,以提高代码效率。

为什么说setTimeout是伪多线程呢。是因为实际还是单线程操作的。再看下一个demo




由于#2基本上不耗时间。write()故意耗掉100ms.

执行结果:

15in953125

执行流程是#1计时开始。#2执行。#3计时开始。#1时间到。发现是空余时间,执行。#1执行过程中,#3时间到。(如果确实是多线程,这时候#3应该也要开始执行了。)实际上。#3发现有代码在执行,等待,直到#1执行完。#3开始执行。可见#1,#3的时间差应该就是一个write()耗的时间数。125-15=110也说明了确实是这样。

用setTimeout的好处就是把代码扔到了空余时间处理。这在处理并发问题时很有用。假设这样一种应用。我服务器往客户端抛数据。客户端接受数据时马上处理。如果服务器是每1ms抛一条数据。而js处理这条数据要两2ms.显然会有数据的丢失,或称为数据淹没。光是这种应用就会丢失50%的数据。事实上如果js处理数据是往DOM上加结点的话。js的耗时会越来越多,越往后丢失的数据越多。处理这种问题就是应用setTimeout().数据来时,我直接抛走。真正的执行是在空闲时间再做。这样就不会有数据丢失了!

现在在做的NBA体育文字直播之前没有用settimeout。所以出现了数据丢失的问题。一百多个用户。实际只处理了30来位。丢失了70%。现在改为setTimeout来做。效果如何,我也试目以待。

js判读浏览器(转载)

function browser() {
    var A = function() {
        var B = navigator.userAgent.toLowerCase(),
        D = function(F, G) {
            if (!F.className) {
                F.className = G
            } else {
                var E = F.className;
                E += (” ” + G);
                F.className = E
            }
        },
        C = function(E) {
            return (B.indexOf(E) != -1)
        };
        D(document.getElementsByTagName(“html”)[0], [(!(/opera|webtv/i.test(B)) && /msie (\d)/.test(B)) ? (“ie ie” + RegExp.$1) : C(“firefox/2”) ? “gecko ff2”: C(“firefox/3”) ? “gecko ff3”: C(“gecko/”) ? “gecko”: C(“chrome/”) ? “chrome”: C(“opera/9”) ? “opera opera9”: /opera (\d)/.test(B) ? “opera opera” + RegExp.$1: C(“konqueror”) ? “konqueror”: C(“applewebkit/”) ? “webkit safari”: C(“mozilla/”) ? “gecko”: “”, (C(“x11”) || C(“linux”)) ? ” linux”: C(“mac”) ? ” mac”: C(“win”) ? ” win”: “”].join(” “))
    } ()
}

if (window.addEventListener) {
    window.addEventListener(“load”, browser, false)
} else {
    if (window.attachEvent) {
        window.attachEvent(“onload”, browser)
    }
};