JavaScript基础笔记(三) 引用类型 引用类型

引用类型的值(对象)是引用类型的一个实例。

一、Object类型

创建Object实例:

 1         //方法一:通过new操作符创建
 2         var a = new Object();
 3         a.neme = "Tom";
 4         a.age = 3;
 5         //方法二:通过对象字面量创建,注意:此时的name什么的不是局部变量,'{}'相当于执行了new操作呢.....
 6         var b = {
 7             name: "Jerry",
 8             age: 3
 9         };
10         var c = {};  //与new Object()相同
11 
12         //对象字面量也是向函数传递大量参数的首选方式
13         function fun(args) {
14             if (typeof args.name == "string") {
15                 //doSth
16             }
17             if (typeof args.age == 'number') {
18                 //doSth
19             }
20         }

访问:

alert(a.name);
alert(a["name"]); //这种语法的优点是可以通过变量访问

二、Array类型

1.数组的每一项可以保存任何类型的数据

2.数组的大小可以动态调整

创建数组

            //方式一:通过new创建
            var a = new Array(6); //创建长度为6的数组
            var b = new Array(1,2,6,8); //定义并初始化一个数组
            //方式二:使用数组字面量
            var c = [18,19,88];
            var d = []; 

检测是否为数组:

alert(a instanceof Array); //该方法在两种不同的全局执行环境下作检测会有问题
//因此可以使用ECMAScript新增的方法:
alert(Array.isArray(a));

转换:

alert(b.join('|')); //1|2|6|8

栈方法(先进后出):

push()函数:接收任意数量的参数,并逐个添加到数组末尾,最后返回修改后数组长度。

pop():从数组末尾移除最后一项,减少数组的length值,返回移除的项。

队列方法(先进先出):

shilft():移除数组的第一项,并返回该项。

unshilt():在数组的前端添加任意个项并返回数组的长度。

重排序:

reverse():反转数组的顺序

sort():该函数调用数组每项(即使该项是数字)的toString()方法,然后比较得到的字符串(当然是按比较字符串的方式)

var a = [5,8,66,89,45,15];
alert(a.sort()); //15,45,5,66,8,89
alert(a); //15,45,5,66,8,89 会改变原数组

这不科学,所以sort()方法接收一个比较函数作为参数

操作方法:

concat()方法:创建数组副本,并把接收到的参数添加到副本末尾,最后返回副本(原数组不改变)

slice()方法:接收一个或者两个参数,起始项和结束项。复制---剪切----返回剪切后的数组

splice()方法:用于删除,插入和替换数组中的项,返回原始数组中的删除项。

splice(arg1,arg2,args3...)

arg1:起始位置

arg2:要删除的项数,插入操作时设置为0

args3:要插入的项,可以为多个

位置方法:

indexOf() lastIndexOf():都接收两个参数,要查找的项和查找起始位置的索引。

迭代方法:

ECMAScript5定义了5个迭代方法,每个方法都接收两个参数:要在每一项运行的函数和运行该函数作用域对象------影响this的值

传入这些方法的函数会接收三个参数:数组项的值,该项在数组中的位置和数组对象本身。

1)every():对数组的每一项都运行给定函数,如果该函数对每一项都返回true则,则every()返回true

2)filter():对数组的每一项运行给定函数,返回该函数会返回true的项组成的新数组

3)forEech():对数组的每一项运行给定函数,无返回值,该操作也不会影响数组。

4)map():对数组的每一项运行给定函数,返回每次函数调用的结果组成的数组

5)some():对数组的每一项运行给定函数,如果该函数对任意一项返回true,则返回true

示例:

            var a = [5,8,66,89,45,15];
            var everyResult = a.every(function (item) {
                return item > 15;
            });
            alert(everyResult);  //false
            var someResult = a.some(function (value) {
                return value > 15;
            });
            alert(someResult);   //true
            var fileterResult = a.filter(function (value) {
                return value > 15;
            });
            alert(fileterResult);  //66,89,45

归并方法:

所谓归并方法:迭代数组的所有项,然后构件一个最终返回值。

ECMAScript5新增了两个归并数组的方法:reduce()    reduceRight()两个方法都接收两个参数,一个是在数组的每一项都会调用的函数,另一个参数是作为递归的初始值。

参数一的函数接收四个参数:前一个值,当前值,项的索引,和数组对象,这个函数的返回值会作为第一个参数传给下一项。

var values = [1,2,3,4,5,6];
var sum = values.reduce(function (pre, cur) {
        return pre+cur;
});
console.log(sum); //21

三、Date类型

ECMAScript使用UTC开始经过的毫秒数来保存时间。

创建:

var date = new Date(); //创建当前时间和日期

重要的方法:

Date.parse():传入表示日期的字符串,返回毫秒数。字符串无法解析返回NaN

Date.UTC():该函数也返回毫秒数,但该函数接收参数:年份,基于0的月份,月份中的哪一天,小时数.......

var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55));

注意Date的构造函数会模仿以上两个函数。

Date.now():放回当前时间毫秒数

其他方法请查看API

四、RegExp类型

ECMAScript通过RegExp类型来支持正则表达式,语法:

var expression = /pattern/flag;
//用RegExp构造函数
var p = new Reg Exp('pattern', 'flag');
//注意由于RegExp构造函数模式参数是字符串,所以有时要进行双重转义。

pattern为正则表达式,flag表面正则表达式行为:

g: 表达式被应用于所有字符串,而非发现第一个时立即停止。

i: 忽略大小写

m: 多行模式

使用正则表达式字面量和使用 RegExp 构造函数创建的正则表达式不一样。在 ECMAScript 3 中,
正则表达式字面量始终会共享同一个 RegExp 实例,而使用构造函数创建的每一个新 RegExp 实例都是 一个新实例。
例如:

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

在第一个循环中,即使是循环体中指定的,但实际上只为/cat/创建了一个 RegExp 实例。由于实
例属性(下一节介绍实例属性)不会重置,所以在循环中再次调用 test()方法会失败。这是因为第一
次调用 test()找到了"cat",但第二次调用是从索引为 3 的字符(上一次匹配的末尾)开始的,所以
就找不到它了。由于会测试到字符串末尾,所以下一次再调用 test()就又从开头开始了。
第二个循环使用 RegExp 构造函数在每次循环中创建正则表达式。因为每次迭代都会创建一个新的
RegExp 实例,所以每次调用 test()都会返回 true
ECMAScript 5 明确规定,使用正则表达式字面量必须像直接调用 RegExp 构造函数一样,每次都创
建新的 RegExp 实例。 IE9+Firefox 4+Chrome 都据此做出了修改。

RegExp实例属性:

global:布尔值,表示是否设置了 g 标志。
ignoreCase:布尔值,表示是否设置了 i 标志。
lastIndex:整数,表示开始搜索下一个匹配项的字符位置,从 0 算起。
multiline:布尔值,表示是否设置了 m 标志。
source:正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回。

RegExp实例方法:

RegExp 对象的主要方法是 exec(),该方法是专门为捕获组而设计的。 exec()接受一个参数,即
要应用模式的字符串,然后返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回 null
返回的数组虽然是 Array 的实例,但包含两个额外的属性: index input。其中, index 表示匹配
项在字符串中的位置,而 input 表示应用正则表达式的字符串。在数组中,第一项是与整个模式匹配
的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组只包含一项)。
请看下面的例子。

    var text = "a home a kid a fool mom and dad and baby";
    var p = /mom (and dad (and baby)?)?/g

    var m = p.exec(text);
    console.log(m.index);
    console.log(m.input);
    console.log(m[0]);
    console.log(m[1]);
    console.log(m[2]);

    /*
    *  20
    *  a home a kid a fool mom and dad and baby
    *  mom and dad and baby
    *  and dad and baby
    *  and baby
    * */

对于 exec()方法而言,即使在模式中设置了全局标志(g),它每次也只会返回一个匹配项。在不
设置全局标志的情况下,在同一个字符串上多次调用 exec()将始终返回第一个匹配项的信息。而在设
置全局标志的情况下,每次调用 exec()则都会在字符串中继续查找新匹配项,如下面的例子所示。

    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

正则表达式的第二个方法是 test(),它接受一个字符串参数。在模式与该参数匹配的情况下返回
true;否则,返回 false

ECMAScript 正则表达式不支持的特性 :
匹配字符串开始和结尾的A
向后查找(lookbehind
并集和交集类
原子组(atomic grouping
Unicode 支持(单个字符除外,如uFFFF
命名的捕获组
ssingle,单行)和 xfree-spacing,无间隔)匹配模式
条件匹配
正则表达式注释


① 但支持以插入符号(^)和美元符号($)来匹配字符串的开始和结尾。
② 但完全支持向前查找(lookahead)。
③ 但支持编号的捕获组。 

五、Function类型

 在ECMAScript中函数实际上是对象,每个函数都是Function类型的实例,函数名实际上是一个指向函数对象的指针,不会与某个函数绑定。

函数的声明:

//方式一,函数声明
function f(a,b){
    //doSth
}
//方式二,函数表达式
var m = function(a,b){
    //doSth
}
//方式三,new操作符
var fun =  new Function("a","b","return a + b"); //不推荐该方式

函数声明与函数表达式的区别:

解析器会率先读取函数声明,并使其在执行任何代码之前可用。

表达式则按照普通表达式的顺序执行。

但这只是执行顺序问题,作用域链不会受影响函数声明出来的f,也是一个带var的变量。

作为值的函数

函数名本来就是变量,因此函数可用作为值来使用,即可用被另一个函数当做参数、返回值。

函数的内部属性:

1)arguments

2)this:指向函数执行环境的变量对象

window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor;
o.sayColor(); //"blue"

3)callee:该属性是一个指针,指向拥有这个arguments对象的函数。使用该属性可以使函数的执行和函数名解耦。

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

4)caller:ECMAScript 5支持,这个属性保存着调用当前函数的函数引用,如果是在全局作用域中调用函数,该属性为null

        window.onload = function () {
            function outer() {
                inner();
            }
            
            function inner() {
                console.log(arguments.callee.caller);
            }

            outer(); //显示outer()函数的源代码
        }

 函数的属性和方法:

length属性:表示函数希望接受命名参数的个数。

proptoype属性:保存所有实例方法。ECMAScript5中该属性不可枚举。

apply()和call()方法:两个方法的用途都是在特定作用域中调用函数

        var a = 8;
        window.onload = function () {
            var obj = {a:99}
            function sum(num1, num2) {
                return num1 + num2 + this.a;
            }

            function sum2(num1, num2) {
                return sum.call(this,num1,num2); //只能这么用,不能像apply那样传入arguments或数组
            }

            function sum3(num1, num2) {
                return sum.apply(this,arguments);
            }

            function sum4(num1, num2) {
                return sum.apply(this,[num1,num2]);
            }

            function sum5(num1, num2) {
                return sum.call(obj,num1,num2); //扩充函数作用域
            }

            function sum6(num1, num2) {
                return sum.apply(obj,arguments);
            }

            console.log(sum2(2,2)); //12
            console.log(sum3(2,2)); //12
            console.log(sum4(2,2)); //12
            console.log(sum5(2,2)); //103
            console.log(sum6(2,2)); //103
        }

ECMAScript5 定义的bind()方法:该方法会返回一个函数的实例,其this值会被绑定为传给bind()的参数

window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue

六、基本包装类型

所谓基本包装类型就是ECMAScript包装的三个特殊引用类型:String,Boolean,Number

每当读取一个基本类型值的时候,后台就会创建一个基本包装类型的对象,从而使我们能调用一些方法来处理数据。

            var str = "The end of the world!"
            console.log(str.substr(3));//end of the world!"

以上代码执行过程:

1)创建一个String类型的实例

2)在实例上调用指定方法

3)销毁该实例

可以想象为代码:

var str = new String("The end of world!");
console.log(str.substring(3));
str = null;

基本包装类型与一般引用类型的主要区别就是对象的生命周期,基本包装类型只存在于执行代码的一瞬间,

执行完毕后立即被销毁。这意味着我们不能为基本包装类型添加属性和方法。

            var str = "High but not dry.";
            str.name = "the cure";
            console.log(str.name);  //undefined

            var str2 = new String("Friday I'm in love.");
            str2.name = "the cure";
            console.log(str2.name); //the cure
          var str = "A letter to Elise";
          var str2 = new String("A letter to Elise");

          console.log(typeof str);         //string
          console.log(typeof "letter");    //string
          console.log(typeof str2);        //object
var value = "25";
var number = Number(value); //转型函数
alert(typeof number); //"number"
var obj = new Number(value); //构造函数
alert(typeof obj); //"object"

一)Boolean

最常见的问题:

var falseObject = new Boolean(false);
var result = falseObject && true;
alert(result); //true

其实也好理解,new(调用构造函数) 出来的在赋值给变量的,永远是一个正真的引用类型,该变量的值是一个引用类型的地址。

二)Number

toFixed()方法:按照指定的小数位返回数值的字符串表示

var num = 10;
alert(num.toFixed(2)); //"10.00"

toExponential()
返回以指数表示法(也称 e 表示法)表示的数值的字符串形式 
toPrecision()会根据要处理的数值决定到底是调用 toFixed()还是调用 toExponential()

三)String

length属性:字符个数

方法:

charAt()

charCodeAt()

contact(str)

str[index]

slice(index,index2)

substr(index,len):第二个参数指定返回字符串个数

substring(index,index2)

trim(str)

以上方法都不影响原字符串

localcompare(str):比较字符串,并返回-1,0,1中的一个

七、单体内置对象

 内置对象:由ECMAScript实现提供,不依赖宿主环境的对象,这些对象在ECMAScript程序执行以前就已经存在。

如:Object、String、Array

一)Global对象

所有在全局域中定义的属性和函数,都是Global对象的属性。浏览器通常将Global对象作为window对象一部分加以实现。

如parseInt(),isNaN()等

1)URI编码方法()略

2)eval()略

二)Math对象