JavaScript小特性(1) – 基本语法

最近看完了《ppk on JavaScript》,一本算是进阶的JavaScript基础书,讲了很多不看书发现不了的小细节,但是都是些很重要的细节,例如事件处理,浏览器兼容等等。

本来打算看O’Reilly的《JavaScript权威指南》(好像是厚厚一大本)巩固一下基础,网易面试那个考官给我推荐的,去图书馆找不着,应该被借了。碰巧发现这本《ppk》,图灵出版,淘宝UED译,应该差不到哪去,就借回去了(而且比较薄,我喜欢薄滴~ [偷笑] )。

下面我就讲些看书中遇到的一些要注意的地方:

1、数据类型转换

JavaScript总的来说只有4种数据类型:number、string、boolean、对象(如果算上undefined和null就6种,NaN是number类型)。

JavaScript是弱变量类型的,一个变量可以存放任意数据类型,而且数据类型可以自动互相转化(这东西看起来方便,却是万恶的根源呀~~)。

var a = '5'//a为string
var b = a * 2;//string与number相乘,b数字
var c = a + b;//因为a是string,表达式变为string
c = new Object();//c被赋值为一个object
if(a && b && c){ //number、string、object自动转为boolean
    //null、undefined、零、NaN都转为false,其他转为true
    //do something
}

问题容易出在哪呢?最常见的就是‘+(加号)’既是加法运算符,又是字符串连接符,导致数字运算经常不知怎么的变成了字符串连接。

介绍几种强制数据类型转换的方法:

  • ” + a -> string
  • a * 1 -> number //如果不能正确转换,则为NaN(not a number)
  • !!a -> bool
  • a.toFixed(num) -> string //转为固定小数位数的字符串(a为number类型)

2011/5/20修订:

+a -> number //同 a*1,此处的“+”是正号的意思

其实,JavaScript有自带的强制转换方法,不过我觉得上面的要方便些

  • Boolean(value) – 把给定的值转换成 Boolean 型;
  • Number(value) – 把给定的值转换成数字(可以是整数或浮点数);
  • String(value) – 把给定的值转换成字符串;

 

顺带说一下浮点数转为整数的几个方法(js的数字类型是不分浮点数与整数的):

  • Math.round(num);//四舍五入
  • Math.floor(num);//向下取整
  • Math.ceil(num);//向上取整

 

2、特殊返回值

JavaScript 的布尔运算 &&、|| 是有返回值的,但不是boolean值,而是该布尔运算计算的最后一个表达式的值

var x = 'JavaScript很诡异';
var y = 'Java很繁琐';
alert(x || y);
//输出:JavaScript很诡异,x转换为true,不继续运算,返回x
alert(x && y);
//输出:Java很繁琐,x转为true,继续运算,返回y

这种特性常用于检测某对象是否存在(虽然&&也可以用来做对象检测,但我们一般不这样做)

function eventHandler(e){//某注册事件的处理函数
	var evt = e || window.event;//获得事件对象,W3C和微软的获取方法不同
	vat evtTarget = evt.target || evt.srcElement;//获取事件目标对象
	//do something
}

另外js里面,=(等号) 也是有返回值的,即可以连续赋值,如:

window.jQuery = window.$ = jQuery

 

3、控制结构

JavaScript支持所有常用的控制结构(这是必须的嘛),如if/else if/else,while/do while,for,continue/break,try/catch/finally …

还有一种for in结构

var test = {
    a:'1',
    b:2,
    c:function(){alert(3)}
}
for(var i in test){
    alert(typeof test[i]);//此处的i是对象的属性名
    //如果是数组,则是数组的索引
}

它还支持使用标签做控制结构,如

outerloop:
for(;;){
	for(;;){
		if(true){
			alert('innerloop');
			break outerloop;//直接跳出外层循环
		}
	}
}
alert('outerloop');

顺便说一个for循环和try/catch结合,解决浏览器工作环境依赖的例子

function createXMLHttpObject(){
	var xmlhttp = false;
	for(var i=0,len=XMLHttpFactories.length;i<len;i++){
		try{
			xmlhttp = XMLHttpFactories[i]();
		}cateh(e){
			//如果产生异常就试下一个
			continue;
		}
		break;//找到就跳出循环
	}
	return xmlhttp;
}
//此数组包含创建XMLHTTP对象的所有可能方式
var XMLHttpFactories = [
	function(){ return new XMLHttpRequest()},
	function(){ return new ActiveXObject('Msxml2.XMLHTTP')},
	function(){ return new ActiveXObject('Msxml3.XMLHTTP')},
	function(){ return new ActiveXObject('Microsoft.XMLHTTP')}
];

 

4、对象/数组

对象和数组为啥要放在一起讲呢,因为我觉得他们在很多地方非常相似,我觉得数组可以算是一种简化版的对象吧(当然数组和对象从本质上还是很大不同的)。

先说几点关于对象和数组的重要的杂事~

  • a、一个数组可以保存多个数据类型,如var arr = [1,’a’,true,function(){alert(‘a’)}];//包括对象、函数、嵌套的数组
  • b、所有的全局变量都包含于一个全局对象window,也就是说 var a = 2 等同于 window.a = 2;//所以说,JavaScript其实是面向对象的,神马都与对象有关~
  • c、所有函数都是一个Function对象(既然是对象,你就可以给他附上各种属性,各种js库就是这样弄出来的),可以通过new FunctionName()的方法来创建新对象;
  • d、‘.(点)’是用于访问对象的属性或方法的,如test.a、test.method(),我们也可以这样:test[‘a’]、test[‘method’](),两种方法等价。后一种访问方式有点像Map,可以当做key/value结构使用;

下面说说对象和数组的字面量,也就是用一个字符串代替对象或者数组的创建(便于信息的传输):

//标准对象创建方法
var test = new Object();
test.a = 100;
test.b = '100';
test.c = function(){alert(test.a*test.b);}

//对象字面量(也就是大名鼎鼎的JSON格式啦~~)
var test = {
	a: 100,//属性名:属性值,结尾有,(逗号)
	b: '100',
	c: function(){alert(test.a*test.b);}//最后一个无,(逗号)
}

//标准数组创建方法
var arr = new Array(1,2,3,4,5);//几乎没人用这种方法吧~

//数组字面量
var arr = [1,2,3,4,5];//这种简单多了

 

5、函数

(此节新增于2011/5/20)

JavaScript里面,所有的函数都是一个对象。我们可以这样创建一个函数:

var sayHello = new Function("toWho", "alert(\"hello \"+toWho+\"!\")");
sayHello("world");

Function对象的构造方法如下(前面的参数是函数接受的参数,最后一是函数体本身,全部都是字符串形式):

var myfun = new function(arg1, arg2, ..., argN, function_body)

Function对象里面有一个特殊的属性,arguments对象,里面包含了函数调用时传入的所有参数

function testArguments(){
	for(var i in arguments){
		alert("arguments["+i+"] : "+arguments[i]);
	}
}

既然所有的function都是一个对象,那么函数名就是指向这一对象的引用,我们可以将一个函数赋值给多个引用

var myfun = function(){

    alert('这是一个函数');
}
var myfun2 = myfun;

myfun();
myfun2();

那么问题又来了,既然函数名是一个引用,那么一个引用当然不能指向多个对象,导致JavaScript并不支持函数重载

虽然函数重载似乎对JavaScript并不是这么重要,但如果真要使用,可以考虑用arguments对象进行模拟函数重载,例如:

function add(){
	if(arguments.length == 1){
		return arguments[0]+1;//自增
	}else if(arguments.length > 1){
		var sum = 0;
		for(var i in arguments){
			sum+=arguments[i];//求和
		}
		return sum;
	}
	return 0;
}
alert(add(1));
alert(add(1,2,3));

JavaScript函数还有一个闭包的特性,欲知详情,请看这里,和这里

 

这篇就先说这么多,下回讲讲BOMDOM相关的东西,例如事件处理、DOM修改神马的~~~

 

我说:说难也不难,说简单又不简单~

发布者

Rolf

伪文艺IT攻城师,热爱前端,热爱互联。

《JavaScript小特性(1) – 基本语法》有2个想法

    1. @虾米 我之前不是在俱乐部上分享过嘛~ 你有没听的……#¥%……@&@*&
      现在回头看这篇文章觉得好肤浅……其实这个系列有好多东西都还没写……

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

[喜欢] [嘻嘻] [奋斗] [问号] [鼓掌] [泪] [酷] [强] [耶] [握手] [心] [给力] [神马] [围观] [奥特曼] more »