javascript笔记

javascript笔记

//定义一个对象 

var obj = new Object(); 

//动态创建属性name 

obj.name = "an object"; 

//动态创建属性sayHi 

obj.sayHi = function(){ 

return "Hi"; 

obj.sayHi(); 

JavaScript中,包含三种基本的数据类型,字符串(String),数值(Number),布尔值(boolean),下面是一些简单的例子: 

var str = "Hello, world";//字符串 

var i = 10;//整型数 

var f = 2.3;//浮点数 

var b = true;//布尔值 

我们可以分别查看变量的值及变量的类型: 

print(str); 

print(i); 

print(f); 

print(b); 

print(typeof str); 

print(typeof i); 

print(typeof f); 

print(typeof b); 

注意,在此处使用的print()函数为rhino解释器的顶层对象的方法,可以用来打印字符串,通常情况下,在客户端,程序员多使用alert()进行类似的动作,alert()是浏览器中JavaScript解释器的顶层对象(window)的一个方法。 

Hello, world 

10 

2.3 

true 

string 

number 

number 

Boolean 

JavaScript中,所有的数字,不论是整型浮点,都属于数字基本类型。typeof是一个一元的操作符.

对象类型不是对象本身,而是指一种类型,我们在第三章会对对象进行详细的讨论,此处的对象包括,对象(属性的集合,即键值的散列表),数组(有序的列表),函数(包含可执行的代码)。 

对象类型是一种复合的数据类型,其基本元素由基本数据类型组成,当然不限于基本类型,比如对象类型中的值可以是其他的对象类型实例,我们通过例子来说明: 

var str = "Hello, world"; 

var obj = new Object(); 

obj.str = str; 

obj.num = 2.3; 

var array = new Array("foo", "bar", "zoo"); 

var func = function(){ 

print("I am a function here"); 

可以看到,对象具有属性,如obj.str, obj.num,这些属性的值可以是基本类型,事实上还可以更复杂,我们来看看他们的类型: 

print(typeof obj); 

print(typeof array); 

print(typeof func); 

//将打印出 

object 

object 

function 

var str = "JavaScript Kernal"; 

print(str.length);//打印17 

对象转换为基本类型则是通过这样的方式:通过调用对象的valueOf()方法来取得对象的值,如果和上下文的类型匹配,则使用该值。如果valueOf取不到值的话,则需要调用对象的toString()方法,而如果上下文为数值型,则又需要将此字符串转换为数值。

valueOf()的作用是,将一个对象的值转换成一种合乎上下文需求的基本类型,toString()则名副其实,可以打印出对象对应的字符串,当然前提是你已经重载ObjecttoString()方法。 

事实上,这种转换规则会导致很多的问题,比如,所有的非空对象,在布尔值环境下,都会被转成true

var x = 3; 

var y = x + "2";// => 32 

var z = x + 2;// => 5 

if(datamodel.item){ 

//do something... 

}else

datamodel.item = new Item(); 

这种写法事实上具有更深层次的含义: 

应该注意到,datamodel.item是一个对象(字符串,数字等),而if需要一个boolean型的表达式,所以这里进行了类型转换。在JavaScript中,如果上下文需要boolean型的值,则引擎会自动将对象转换为boolean类型。转换规则为,如果该对象非空,则转换为true,否则为false.因此我们可以采取这种简写的形式。 

function handleMessage(message, handle){ 

if(typeof handle == "function"){ 

return handle(message); 

}else

throw new Error("the 2nd argument should be a function"); 

但是,typeof并不总是有效的,比如下面这种情况: 

var obj = {}; 

var array = ["one", "two", "three", "four"]; 

print(typeof obj);//object 

print(typeof array); //object 

运行结果显示,对象obj和数组arraytypeof值均为object,这样我们就无法准确判断了,这时候,可以通过调用instanceof来进行进一步的判断: 

print(obj instanceof Array);//false 

print(array instanceof Array);//true 

第一行代码返回false,第二行则返回true。因此,我们可以将typeof操作符和instanceof操作符结合起来进行判断。 

[]可以作用于对象,一般而言,对象中的属性的值是通过点(.)运算符来取值,如: 

var object = { 

field : "self", 

printInfo : function(){ 

print(this.field); 

object.field; 

object.printInfo(); 

但是考虑到这样一种情况,我们在遍历一个对象的时候,对其中的属性的键(key)是一无所知的,我们怎么通过点(.)来访问呢?这时候我们就可以使用[]运算符: 

for(var key in object){ 

print(key + ":" + object[key]); 

运行结果如下: 

field:slef 

printInfo:function (){ 

print(this.field); 

点运算符的左边为一个对象(属性的集合),右边为属性名,应该注意的是右边的值除了作为左边的对象的属性外,同时还可能是它自己的右边的值的对象: 

var object = { 

field : "self", 

printInfo : function(){ 

print(this.field); 

}, 

outter:{ 

inner : "inner text", 

printInnerText : function(){ 

print(this.inner); 

object.outter.printInnerText(); 

这个例子中,outter作为object的属性,同时又是printInnerText()的对象。 

但是点(.)操作符并不总是可用的,考虑这样一种情况,如果一个对象的属性本身就包含点(.)的键(self.ref),点操作符就无能为力了: 

var ref = { 

id : "reference1", 

func : function(){ 

return this.id; 

}; 

var obj = { 

id : "object1", 

"self.ref" : ref 

}; 

当我们尝试访问objself.ref这个属性的时候:obj.self.ref,解释器会以为obj中有个名为self的属性,而self对象又有个ref的属性,这样会发生不可预知的错误,一个好的解决方法是使用中括号([])运算符来访问: 

print(obj["self.ref"].func()); 

运算符==读作相等,而运算符===则读作等同。这两种运算符操作都是在JavaScript代码中经常见到的,但是意义则不完全相同,简而言之,相等操作符会对两边的操作数做类型转换,而等同则不会。我们还是通过例子来说明: 

print(1 == true); 

print(1 === true); 

print("" == false); 

print("" === false); 

print(null == undefined); 

print(null === undefined); 

运行结果如下: 

true 

false 

true 

false 

true 

false 

相等和等同运算符的规则分别如下: 

相等运算符 

如果操作数具有相同的类型,则判断其等同性,如果两个操作数的值相等,则返回true(相等),否则返回false(不相等). 

如果操作数的类型不同,则按照这样的情况来判断: 

nullundefined相等 

其中一个是数字,另一个是字符串,则将字符串转换为数字,在做比较 

其中一个是true,先转换成1(false则转换为0)在做比较 

如果一个值是对象,另一个是数字/字符串,则将对象转换为原始值(通过toString()或者valueOf()方法

其他情况,则直接返回false 

等同运算符 

如果操作数的类型不同,则不进行值的判断,直接返回false 

如果操作数的类型相同,分下列情况来判断: 

都是数字的情况,如果值相同,则两者等同(有一个例外,就是NaNNaN与其本身也不相等),否则不等同 

都是字符串的情况,与其他程序设计语言一样,如果串的值不等,则不等同,否则等同 

都是布尔值,且值均为true/false,则等同,否则不等同 

如果两个操作数引用同一个对象(数组,函数),则两者完全等同,否则不等同 

如果两个操作数均为null/undefined,则等同,否则不等同 

//声明一个对象 

var jack = new Object(); 

jack.name = "jack"; 

jack.age = 26; 

jack.birthday = new Date(1984, 4, 5); 

//声明另一个对象 

var address = new Object(); 

address.street = "Huang Quan Road"; 

address.xno = "135"; 

//addr属性赋值为对象address 

jack.addr = address; 

JSON的应用场景是:当一个函数拥有多个返回值时,在传统的面向对象语言中,我们需要组织一个对象,然后返回,而JavaScript则完全不需要这么麻烦,比如: 

function point(left, top){ 

this.left = left; 

this.top = top; 

//handle the left and top 

return {x: this.left, y:this.top}; 

直接动态的构建一个新的匿名对象返回即可: 

var pos = point(3, 4); 

//pos.x = 3; 

//pos.y = 4; 

使用JSON返回对象,这个对象可以有任意复杂的结构,甚至可以包括函数对象。 

在实际的编程中,我们通常需要遍历一个JavaScript对象,事先我们对对象的内容一无所知。怎么做呢?JavaScript提供了for..in形式的语法糖: 

for(var item in json){ 

//item为键 

//json[item]为值 

函数在JavaScript中可以: 

Ø 被赋值给一个变量 

Ø 被赋值为对象的属性 

Ø 作为参数被传入别的函数 

Ø 作为函数的结果被返回 

Ø 用字面量来创建 

JavaScript中,函数的参数是比较有意思的,比如,你可以将任意多的参数传递给一个函数,即使这个函数声明时并未制定形式参数

事实上,JavaScript在处理函数的参数时,与其他编译型的语言不一样,解释器传递给函数的是一个类似于数组的内部值,叫arguments

function sum(){ 

var result = 0; 

for(var i = 0, len = arguments.length; i < len; i++){ 

var current = arguments[i]; 

if(isNaN(current)){ 

throw new Error("not a number exception"); 

}else

result += current; 

return result; 

print(sum(10, 20, 30, 40, 50)); 

print(sum(4, 8, 15, 16, 23, 42));//《迷失》上那串神奇的数字 

print(sum("new")); 

函数sum没有显式的形参,而我们又可以动态的传递给其任意多的参数,那么,如何在sum函数中如何引用这些参数呢?这里就需要用到arguments这个伪数组了,运行结果如下: 

150 

108 

Error: not a number exception 

赋值给一个变量: 

//声明一个函数,接受两个参数,返回其和 

function add(x, y){ 

return x + y; 

var a = 0; 

a = add;//将函数赋值给一个变量 

var b = a(2, 3);//调用这个新的函数

print(b); 

这段代码会打印5,因为赋值之后,变量a引用函数add,也就是说,a的值是一个函数对象(一个可执行代码块),因此可以使用a(2, 3)这样的语句来进行求和操作。 

赋值为对象的属性: 

var obj = { 

id : "obj1" 

obj.func = add;//赋值为obj对象的属性 

obj.func(2, 3);//返回

事实上,这个例子与上个例子的本质上是一样的,第一个例子中的a变量,事实上是全局对象(如果在客户端环境中,表示为window对象)的一个属性。而第二个例子则为obj对象,由于我们很少直接的引用全局对象,就分开来描述。 

作为参数传递: 

//高级打印函数的第二个版本 

function adPrint2(str, handler){ 

print(handler(str)); 

//将字符串转换为大写形式,并返回 

function up(str){ 

return str.toUpperCase(); 

//将字符串转换为小写形式,并返回 

function low(str){ 

return str.toLowerCase(); 

adPrint2("Hello, world", up); 

adPrint2("Hello, world", low); 

运行此片段,可以得到这样的结果: 

HELLO, WORLD 

hello, world


var array = new Array(1, 2, 3, 4, 5); 

print(array.length); //得到数组长度

另一个与其他语言的数组不同的是,字符串也可以作为数组的下标,事实上,在JavaScript的数组中,字符串型下标和数字型的下标会被作为两个截然不同的方式来处理,一方面,如果是数字作为下标,则与其他程序设计语言中的数组一样,可以通过index来进行访问,而使用字符串作为下标,就会采用访问JavaScript对象的属性的方式进行,毕竟JavaScript内置的Array也是从Object上继承下来的。比如: 

var stack = new Array(); 

stack['first'] = 3.1415926; 

stack['second'] = "okay then."; 

stack['third'] = new Date(); 

for(var item in stack){ 

print(typeof stack[item]); 

运行结果为: 

number 

string 

object 

向数组中添加元素: 

var array = []; 

array.push(1); 

array.push(2); 

array.push(3); 

array.push("four"); 

array.push("five"); 

array.push(3.1415926); 

前面提到过,JavaScript的数组有列表的性质,因此可以向其中push不同类型的元素,接上例: 

var len = array.length; 

for(var i = 0; i < len; i++){ 

print(typeof array[i]); 

结果为: 

number 

number 

number 

string 

string 

number 

弹出数组中的元素: 

for(var i = 0; i < len; i++){ 

print(array.pop()); 

print(array.length); 

运行结果如下,注意最后一个0是指array的长度为0,因为这时数组的内容已经全部弹出: 

3.1415926 

five 

four 

join,连接数组元素为一个字符串: 

array = ["one", "two", "three", "four", "five"]; 

var str1 = array.join(","); 

var str2 = array.join("|"); 

print(str1); 

print(str2); 

运行结果如下: 

one,two,three,four,five 

one|two|three|four|five 

连接多个数组为一个数组: 

var another = ["this", "is", "another", "array"]; 

var another2 = ["yet", "another", "array"]; 

var bigArray = array.concat(another, another2); 

结果为: 

one,two,three,four,five,this,is,another,array,yet,another,array 

从数组中取出一定数量的元素,不影响数组本身: 

print(bigArray.slice(5,9)); 

结果为: 

this,is,another,array 

slice方法的第一个参数为起始位置,第二个参数为终止位置,操作不影响数组本身。下面我们来看splice方法,虽然这两个方法的拼写非常相似,但是功用则完全不同,事实上,splice是一个相当难用的方法: 

bigArray.splice(5, 2); 

bigArray.splice(5, 0, "very", "new", "item", "here"); 

第一行代码表示,从bigArray数组中,从第5个元素起,删除2个元素;而第二行代码表示,从第5个元素起,删除0个元素,并把随后的所有参数插入到从第5个开始的位置,则操作结果为: 

one,two,three,four,five,very,new,item,here,another,array,yet,another,array 

我们再来讨论下数组的排序,JavaScript的数组的排序函数sort将数组按字母顺序排序,排序过程会影响源数组,比如: 

var array = ["Cisio", "Borland", "Apple", "Dell"]; 

print(array); 

array.sort(); 

print(array); 

执行结果为:

Cisio,Borland,Apple,Dell 

Apple,Borland,Cisio,Dell 

这种字母序的排序方式会造成一些非你所预期的小bug,比如: 

var array = [10, 23, 44, 58, 106, 235]; 

array.sort(); 

print(array); 

得到的结果为: 

10,106,23,235,44,58 

可以看到,sort不关注数组中的内容是数字还是字母,它仅仅是按照字母的字典序来进行排序,对于这种情况,JavaScript提供了另一种途径,通过给sort函数传递一个函数对象,按照这个函数提供的规则对数组进行排序。 

 function sorter(a, b){ 

return a - b; 

var array = [10, 23, 44, 58, 106, 235]; 

array.sort(sorter); 

print(array); 

函数sorter接受两个参数,返回一个数值,如果这个值大于0,则说明第一个参数大于第二个参数,如果返回值为0,说明两个参数相等,返回值小于0,则第一个参数小于第二个参数,sort根据这个返回值来进行最终的排序: 

10,23,44,58,106,235 

当然,也可以简写成这样: 

array.sort(function(a, b){return a - b;});//正序 

array.sort(function(a, b){return b - a;});//逆序 

邮箱地址正则var emailval = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/; 

emailval.test("[email protected]");//true 


你可能感兴趣的:(javascript笔记)