深夜课堂:javascript 引用类型(1)

引用类型是一种数据结构,用于将数据和功能组织在一起。有时,引用类型也被称为类,但是这种说法其实不太准确:尽管ECMAScript从技术上讲是一门面向对象的语言,但是它并不具有传统的面向对象语言所支持的类的借口等基本结构。也就是说,引用类型和类,并不是同一个概念。

1、object类型:
两种定义方式:

var person = new Object();
person.name = "Nicholas";
person.age = 29;
var person = {
    name : "Nicholas",
    age : 29
};

第二种定义方式需要注意,在最后一个属性的后面不可以加上逗号,否则,会在IE7和Opera中导致错误。
对于上述对象属性的访问,也有如下两种方式:

alert(person["name"]); //"Nicholas" 
alert(person.name); //"Nicholas"

方括号的优点是可以通过变量访问属性:

var propertyName = "name"; 
alert(person[propertyName]); //"Nicholas"

但是,除非必须使用变量来访问属性,否则我们建议使用点表示法。

2、Array类型:
创建数组的方式:

var colors = new Array();

var colors = new Array(20);

var colors = new Array("red", "blue", "green");

var values = [1,2,];//不要这样创建,在不同浏览器中,会创建出不同长度的数组

数组的length属性可以返回数组的长度,而且它有一个很有趣的特点:它不是只读的。通过设置这个属性,可以为数组增加或删除元素,新增的元素就是undefined。

var colors = ["red", "blue", "green"];
colors.length = 4;
alert(colors[3]); //undefined

判断一个变量是否为数组的方法:

var value = new Array();
if (value instanceof Array){
    // 对数组的操作   
}

然而该方法存在一个问题:它假定只有一个全局环境。但是如果网络包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在多个不同版本的Array构造函数。
为了解决这个问题,还新增了方法:Array.isArray()

if (Array.isArray(value)){
    //  对数组的操作
}

支持这个方法的浏览器有:IE9+、Firefox 4+、Safari 5+、Opera 10.5+和Chrome。

var colors = ["red", "blue", "green"];
alert(colors.toString());   // red,blue,green
alert(colors.valueOf());    // red,blue,green
alert(colors);              // red,blue,green

最后一句当中,由于alert需要字符串参数,所以后台会自动调用toString()方法。
另外,toLocaleString()也会返回和toString()方法相同的值。

var person1 = {
    toLocaleString : function () {
        return "Nikolaos";
    },
    toString : function() {
        return "Nicholas";
} };
var person2 = {
    toLocaleString : function () {
        return "Grigorios";
    },
    toString : function() {
        return "Greg";
} };
var people = [person1, person2];
alert(people);
alert(people.toString());
alert(people.toLocaleString());
//Nicholas,Greg
//Nicholas,Greg
//Nikolaos,Grigorios

另外,数组还有join函数

var colors = ["red", "green", "blue"];
    alert(colors.join(","));       //red,green,blue
    alert(colors.join("||"));      //red||green||blue

注:如果数组中的某一项为空或者未定义undefined,那么上述几个函数返回的结果将以空字符串表示。

堆栈方法和队列方法:

var colors = new Array();
var count = colors.push("red", "green"); 
alert(count); //2
count = colors.push("black");
alert(count);     //3
var item = colors.shift();// 取得第一项
alert(item); //"red" 
alert(colors.length); 
var colors = new Array(); 
colors.unshift("red", "green");//在数组前端添加项  
alert(count); //2
count = colors.unshift("black");
alert(count);   //3
var item = colors.pop();
alert(item);    //"green"
alert(colors.length); //2

重排序方法:

var values = [1, 2, 3, 4, 5]; 
values.reverse();
alert(values); //5,4,3,2,1
var values = [0, 1, 5, 10, 15];
values.sort();
alert(values);     //0,1,10,15,5

sort函数可以接受一个函数作为参数,让我们可以自己定义如何比较:

function compare(value1, value2) {
    if (value1 < value2) {
        return -1;
    } else if (value1 > value2) {
        return 1;
    } else {
return 0; }
}

var values = [0, 1, 5, 10, 15];
    values.sort(compare);
alert(values); //0,1,5,10,15

数组的迭代方法:

var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item, index, array){
         return (item > 2);
});
alert(everyResult); //false

var someResult = numbers.some(function(item, index, array){
         return (item > 2);
});
alert(someResult); //true

var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item, index, array){
    return (item > 2);
 });
alert(filterResult);//[3,4,5,4,3]

var numbers = [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item, index, array){
    return item * 2;
});
alert(mapResult);  //[2,4,6,8,10,8,6,4,2]

var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item, index, array){
    // 执行某些操作
});

数组的归并方法:
支持该方法的浏览器包括:IE9+ Firefox 3+ Safari 4+ Opera 10.5和Chrome。

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
    return prev + cur;
});
alert(sum); //15

3、Date类型:

var now = new Date();
var someDate = new Date(Date.parse("May 25, 2004"));// 接受一个表示日期的字符串参数,然后根据这个字符串返回相应日期的毫秒数。
var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55));// 2005年5月5日下午5:55:55。注意这里是5月,因为1月对应的是数字零。

var start = Date.now();// 返回当前时间

不同浏览器返回的函数值不同:

Internet Explorer 8
toLocaleString()   Thursday, February 01, 2007 12:00:00 AM toString()   Thu Feb 1 00:00:00 PST 2007

Firefox 3.5
toLocaleString()   Thursday, February 01, 2007 12:00:00 AM
toString()   Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)

Safari 4
toLocaleString()   Thursday, February 01, 2007 00:00:00
toString()   Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)

Chrome 4
toLocaleString()   Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time) 
toString()   Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)

Opera 10
toLocaleString()   2/1/2007 12:00:00 AM 
toString()   Thu, 01 Feb 2007 00:00:00 GMT-0800

4、RegExp类型
ECMAScript通过RegExp类型支持正则表达式。

var expression = / pattern / flags ;

flag:
g:表示全局模式,即模式会被用于所有字符串,而非在发现第一个字符串后立即停止。
i:不区分大小写。
m:多行模式。
栗子:

var pattern1 = /at/g;   //匹配所有带at的字符串。
var pattern2 = new RegExp("at", "i");   // 另一种创建方式。

两种方法的区别:


    var re = null,
    var i;
    for (i=0; i < 10; i++){
        re = /cat/g;
        re.test("catlikefish");
    }
    for (i=0; i < 10; i++){
        re = new RegExp("cat", "g");
        re.test("catlikefish");
    }

第一种方式中,只会为cat创建一个实例,实例的属性不会重置,因此第二次调用test的时候会失效。
第二种方式,每次都创建一个新的实例,因此test总可以返回正确的值。

实例方法:

var text = "mom and dad and baby";
var pattern = /mom( and dad( and baby)?)?/gi;
var matches = pattern.exec(text);
alert(matches.index); //0
alert(matches.input); //mom and dad and baby
alert(matches[0]);//mom and dad and baby
alert(matches[1]);//and dad and baby
alert(matches[2]);//and baby
var text = "cat, bat, sat, fat";
var pattern1 = /.at/;
var matches = pattern1.exec(text);
alert(matches.index);        //0
alert(matches[0]);           //cat
alert(pattern1.lastIndex);   //0

matches = pattern1.exec(text); 
alert(matches.index); //0 
alert(matches[0]); //cat 
alert(pattern1.lastIndex); //0

var pattern2 = /.at/g;

var matches = pattern2.exec(text); 
alert(matches.index); //0 
alert(matches[0]); //cat 
alert(pattern2.lastIndex); //3

matches = pattern2.exec(text);
alert(matches.index);        //5
alert(matches[0]);           //bat
alert(pattern2.lastIndex);   //8

5、Function类型
Function是JavaScript最精彩的部分!

// 定义方法1、2
function sum (num1, num2) {
        return num1 + num2;
}
var sum = function(num1, num2){
        return num1 + num2;
};
// 函数名仅仅是指向函数的指针。
function sum(num1, num2){
    return num1 + num2;
}
alert(sum(10,10));        //20
var anotherSum = sum;
alert(anotherSum(10,10)); //20
sum = null;
alert(anotherSum(10,10)); //20

js函数不重载,后写的函数会覆盖前面的函数。

// 正常运行
alert(sum(10,10));
function sum(num1, num2){
    return num1 + num2;
}

// 出现错误
alert(sum(10,10));
var sum = function(num1, num2){
    return num1 + num2;
};

函数可以作为参数!

function callSomeFunction(someFunction, someArgument){
        return someFunction(someArgument);
}
function add10(num){
        return num + 10;
}
    var result1 = callSomeFunction(add10, 10);
    alert(result1);   //20
    function getGreeting(name){
    return "Hello, " + name;
}
var result2 = callSomeFunction(getGreeting, "Nicholas");
alert(result2);   //"Hello, Nicholas"

同时,这也就意味着,函数也可以作为返回值!

function createComparisonFunction(propertyName) {
        return function(object1, object2){
            var value1 = object1[propertyName];
            var value2 = object2[propertyName];
            if (value1 < value2){
                return -1;
            } else if (value1 > value2){
                return 1;
            }else{
                return 0;
            }
        };
}

函数的内部属性:
在函数内部,有两个特殊的对象,arguments和this。
关于arguments的用法,虾面两段代码是一样的:

function factorial(num){
        if (num <=1) {
            return 1;
        } else {
            return num * factorial(num-1)
        }
}
function factorial(num){
    if (num <=1) {
        return 1;
    } else {
        return num * arguments.callee(num-1)
    } 
}

后面这个函数的好处是,在函数内部没有出现函数名factorial,这样修改函数名会变得方便。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值