JavaScript高级程序设计学习笔记5

第5章 引用类型

在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起。它也被称为,但这种称呼并不妥当。尽管从技术讲是一门面向对象的语言,但是她不具备传统的面向对象语言所支持的类和接口等基本结构。

对象时某个特定引用类型的实例。

新对象使用new操作符后更一个构造函数来创建。

构造函数本身就是一个函数,只不过该函数是出于创建新对象的目的而定义的。

5.1 Object类型

Object类型时ECMAScript中使用最多的一个类型,虽然不具备多少功能,但在应用程序中存储数和传输数据而言,它们确实是非常理想的选择。

创建Object实例的方法有两种:
1.使用new操作符后跟object函数

var person = new Object();
person.name ="Fred";
person.age = 20;

2.使用对象字面量表示法。
对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性对象的过程。

var person = {
    name:"Fred",
    age :20
};

一般来说访问对象属性时使用的都是点表示法。不过在JS中也可以使用方括号表示法来访问对象属性。在使用方括号语法时,应该将要访问的属性一字符串的形式放在方括号中。

方括号语法的主要优点是可以通过变量来访问属性。
通常,除非必须使用变量来访问属性,否则我们建议使用点表示法。

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

5.2 Array类型

ECMAScript的数组类型与其他多数语言中的数组有着相当大的差别,
ECMAScript数组的每一项可以保存任何类型的数据,
也就是说数组的第一个位置来保存字符串,第二个位置可以来保存数值,第三个位置可以来保存对象。
ECMAScript数组的大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新数据

创建数组的方式有两种:
1.使用Array构造函数

var colors = new Array();
var names = new Array(3);
var colors = new Array("red","blue","green");
var names = new Array("Grey"); //创建一个包含1项,即字符串“Grey”的数组

2.使用数组字面量表示法

var colors = ["red","blue","green"];    //创建一个包含三个字符串的数组
var names =[ ];                         //创建一个空数组
var values = [1,2,];                    //不要这样,创建一个包含2或三项的数组
var options = [,,,,,];                  //不要这样,创建一个包含5或6项的数组

在读取和设置数组的值时,要使用方括号并提供相应值的基于0的数字索引

var colors = ["red","blue","green"];    //定义一个字符串数组
alert(colors[0]);                       //显示第一项
colors[2] = "black";                    //修改第三项
colors[3] = "brown";                    //添加第四项

数组的项数保存在其length属性中,这个属性始终会返回0或更大的值。
length不是只读的,因此通过设置这个属性,可以从数组的末尾移除项或者向数组中添加新项。

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

利用length在末尾添加新项目

var colors = ["red","blue","green"];
colors[colors.length] = "black";    //在位置3添加
colors[colors.length] = "brown";    //在位置4添加

colors[99] = "white";
alter(colors.length);               //100,位置5到99都是undefined

5.2.1 检测数组

对于一个网页或者一个全局作用域而言:

if(value instanceof Array){
//对数组执行某些操作
}

多个全局执行环境中,最终确定某个值到底是不是数字

if(Array.isArray(value)){
//对数组执行某些操作
}

5.2.2 转换方法

  • toString
  • valueOf
  • toLocaleString

使用join()方法可以使用不同的分隔符来构建字符串

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

5.2.3 栈方法

栈是一种LIFO结构,后进先出,栈中项的插入和移除只发生在栈的顶部。
ECMAScript专门为数组提供了push()和pop()方法。

push()方法可以接受任意数量的参数,把他们逐个添加到数组末尾,并返回修改后的数组长度。
pop()方法则从数组末尾移除最后一项,减少数组的length值,然后返回移除的项。

var colors = new Array();
count = colors.push("red","blue");
alert(count);   //2

count = colors.push("green")l
alert(count);   //3

item = colors.pop();
alter(item);    //"green"
alter(colors.length)    //2

5.2.4 队列方法

队列数据结构的访问规则是FIFO
队列在列表的末端添加项,在列表的前端移除项
shift()能够移除数组中的第一个项,并返回该项,同时将数组长度减1

var colors = new Array();
var count = colors.push("red","green");
alter(count);       //2

count = colors.push("black");
alter(count);       //3

var item = colors.shift();
alter(item);        //"red"
alter(colors.length);   //2

unshift() 能在数组前端添加人一个项并返回新数组的长度。因此同时使用unshift()和pop()能够从相反方向来模拟队列

5.2.5 重排序方法

reverse()会翻转数组项的顺序
sort()方法按升序排列数组项,sort方法会调用每个数组项的toString()转型方法,然后比较得到字符串,以确定如何排序。

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{
        retrun 0;
    }
}

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

*5.2.6 操作方法

concat()基于当前数组中的所有项创建一个新数组

var colors = ["red","green","blue"];
var colors2 = color.concat("yellow",["black","brown"]);

alter(colors);      //red,green,blue
alter(colors2);     //red,green,blue,yellow,black,brown

slice()基于当前数组中的一个或多个项创建一个新数组
一个参数,返回参数指定位置开始到当前数组末尾的所有项
两个参数,返回参数指定位置开始到结束位置之间(不含结束位置)的所有项

var colors = ["red","green","blue","yellow","purple"];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,4);

alert(colors2); //green,blue,yellow,purple
alert(colors3); //green,blue,yellow

splice() 最强大的数组方法,向数组的中部插入项

  • 删除:可以删除任意数量的项,指定2个参数:要删除的第一项的位置和删除的项数 splice(0,2)会删除数组中的前两项
  • 插入:可以向指定位置插入任意数量的项,只需3个参数:起始位置、0(要删除的项)和要插入的项。 splice(2,0,“red”,”green”)会从位置2插入字符串“red”和”green”
  • 替换:可以向指定位置插入任意数量的项,同时删除任意数量的项,只需3个参数:起始位置、要删除的项数和要插入的项
var colors = ["red","green","blue"];
var removed = colors.splice(0,1);
alert(colors); //green,blue
alert(removed);//red

removed = colors.splice(1,0,"yellow","orange");//从位置1插入2项
alter(colors);  //green,yellow,orange,blue
alter(removed); //空数组

removed = colors.splice(1,1,"red","purple");//从位置1插入2项
alter(colors);  //green,red,purple,orange,blue
alter(removed); //yellow

5.2.7 位置方法

indexOf()
lastIndexOf()
这两个方法都接收两个参数:要查找的项和表示查找起点位置的索引。
indexOf的方法是从数组头开始向后查找
lastIndexOf的方法是从数组尾开始向前查找
这两个方法都要返回要查找的项在数组中的位置,或者在没找到的情况下返回-1
在比较时使用全等操作符

var numbers=[1,2,3,4,5,6];
alert(numbers.indexOf(4));//3

5.2.8 迭代方法

  • every()对数组中的每一项运行给定函数,如果该函数对每一项都返回true则返回true
  • filter()对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组
  • forEach()没返回值
  • map()对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
  • some()对数组中的每一项运行给定函数,如果该函数对某一项返回true,就会返回true。

5.2.9 归并方法

reduce()

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

reduceRight()

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

5.3 Date类型

创建日期对象:

var now = new Date();
Date.parse();//接收一个表示日期的字符串参数

var someDate = new Date(Date.parse("May 25,2004"));
var allFives = new Date(Date.UTC(2015,4,5,17,55,55));//GTM时间2015.5.5下午5.55.55

var start = Date.now();
doSomething();
var stop = Date.now();
    result = stop - start;

5.3.1 继承的方法

5.3.2 日期格式化的方法

  • toDateString()
  • toTimeString()
  • toLocaleDateString()
  • toLocaleTimeString()
  • toUTCString

5.3.3 日期时间组件方法

  • get/setTime
  • get/setFullYear(年)
  • get/setMonth(月)
  • get/setDate(日)
  • get/setHours(时)
  • get/setMinutes(分)
  • get/setSeconds(秒)
  • getDay(星期)
var d = new Date();
var week = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"];
document.write(d.getFullYear()+"年");
document.write(d.getMonth()+"月");
document.write(d.getDate()+"日");
document.write(" "+week[d.getDay()]);

5.4 RegExp类型

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

var expression = /pattern / flags;

pattern部分可以是任何简单或复杂的正则表达式
每个正则都可以带一个或多个标志flag
正则表达式的匹配模式支持下列3个标志

  • g:表示全局模式
  • i:表示不区分大小写模式
  • m:表示多行模式

与其他语言中的正则表达式类似,模式中使用的所有元字符都必须转义。元字符包括:([{\^$|)?*+.]}

5.4.1 RegExp实例属性

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

5.4.2 RegExp实例方法

RegExp对象的主要方法是exec(),该方法是专门为捕获组而设计的。
exec()接收一个参数,即要应用模式的字符串,然后返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回null。
index表示匹配项在字符串中的位置
input表示应用正则表达式的字符串。

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(pattern1.lastIndex);          //8

第二个方法是test();它接收一个字符串参数。在模式与该参数匹配的情况下返回true。

/*验证用户输入*/
var text = "000-00-0000";
var pattern = /\d{3}-\d{2}-\d{4}/;

if(pattern.test(text)){
alert("The pattern was matched.");
}

5.4.3 RegExp构造函数属性

长属性名短属性名说明
input$_最近一次要匹配的字符串
lastMatch$&最近一次的匹配项
lastParen$+最近一次的捕获组
leftContext$`input字符串中lastMatch之前的文本
multiline$*布尔值,表示是否所有表达式都使用多行模式
rightContext$’Input字符串中lastMatch之后的文本
var text = "this has been a short summer";
var pattern = /(.)hort/g;

if(pattern.test(text)){
    alert(RegExp.input);     //this has been a short summer
    alert(RegExp.leftContext);//this has been a 
    alert(RegExp.rightContext);//summer
    alert(RegExp.lastMatch);//short
    alert(RegExp.lastParen);//s
    alert(RegExp.multiline);//undefined
}

短属性名要用方括号来访问

5.4.4 模式的局限性

不支持的特性

  • 匹配字符串开始和结尾的锚
  • 向后查找
  • 并集和交集类
  • 原子组
  • Unicode支持
  • 命名的捕获组
  • s和x匹配模式
  • 条件匹配
  • 正则表达式注释

5.5 Function类型

function sum (num1,num2){
    return num1+num2;
}
var sum = function(num1,num2){
    return num1+num2;
};
var sum = new Function("num1","num2","return num1 + num2");//不推荐

5.5.1 没有重载

声明两个同名函数,而结果则是后面的函数覆盖了前面的函数。

5.5.2 函数声明与函数表达式

解析器在向执行环境中加载数据时,对函数声明和 函数表达式并非一视同仁。解析器会率先读取函数声明,并使其在执行任何代码之前可用;之余函数表达式,必须等到解析器执行到他所在的代码行,才会真正被解析。

//运行正常
alert(sum(10,10));
function sum(a,b){
    return a+b;
}
//产生错误
alert(sum(10,10))
var sum = function(a,b){    //不是函数声明,函数只是位于一个初始化语句中
    return a+b;
}

5.5.3 作为值的函数

函数作为参数值

function callSomeFunction(someFunction,someArgument){
    return someFunction(someArgument);
}

function add10(num){
    return num + 10;
}

var result1 = callSomeFunction(add10,10)
alert(result1);

function getGreeting(name){
    return "Hello " + name;
}
var result2 = callSomeFunction(getGreeting,"Fred");
alert(result2);

函数作为返回值

function creatComparisonFunction(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;
        }
    }
}

var data = [{name:"Fred",age:28},{name:"Rose",age:20}];

data.sort(creatComparisonFunction("name"));
alert(data[0].name);

data.sort(creatComparisonFunction("age"));
alert(data[0].name);

5.5.4 函数内部属性

在函数内部,有两个特殊对象:arguments和this。
arguments用于保存函数参数,这个对象还有个名为callee的属性,是一个指针,指向拥有这个arguments对象的函数

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

var truFactorial = factorial;
factorial = function()
{
    return 0;
}

alert(trueFactorial(5));    //120
alert(factorial(5));        //0

如果使用注释的递归返回,alert(trueFactorial(5))则会显示为0。

函数内部的另一个特殊对象时this,其行为与java和c#中的this大致类似,
this引用的是函数据以执行的环境对象——或者也可以说是this值。
当在网页的全局作用域中调用函数时,this对象引用的就是window。

window.color = "red";
var o = {color:"blue"};

function sayColor(){
    alert(this.color);
}

sayColor();
o.sayColor = sayColor;
o.sayColor();

caller属性保存着调用当前函数的函数的引用,如果在全局作用域中调用当前函数,它的值为null。

function outer(){
    inner();
}

function inner(){
    //alert(inner.caller);
    alert(arguments.callee.caller);
}
outer();

5.5.5 函数属性和方法

每个函数包含两个属性length和prototype。
length表示函数希望接受的命名参数个数

在创建自定义引用类型以及实现继承时,prototype属性的作用是极为重要的

每个函数都包含两个非继承而来的方法:apply和call
apply方法接收两个参数,一个是在其中运行函数的作用域,另一个是参数数组

function sum(num1,num2){
    return num1 + num2;
}

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

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

alert(callSum1(10,10));
alert(callSum2(10,10));

call方法与apply方法的作用相同,他们的区别仅在于接收参数的方式不同。call除第一个参数this以外的其他参数都是直接传递给函数。

事实上,传递函数并非apply和callde 真正用武之地。他们真正强大的地方是扩充函数赖以运行的作用域。

window.color ="red";
var o = {color:"blue"};

function sayColor(){
    alert(this.color);
}

sayColor();
sayColor.call(this);
sayColor.call(window);
sayColor.call(o);       //blue

bind这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。

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

5.6 基本包装类型

使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型对象,则值存在于一行代码的执行瞬间,然后立即被销毁。
这意味着我们不能再运行时为基本类型添加属性和方法。

5.6.1 Boolean

建议永远不要使用boolean

5.6.2 Number类型

  • toString()方法传递一个表示基数的参数
  • toFixed()指定的小数位返回数值的字符串
  • toExponential()用于格式化数值

5.6.3 String类型

1.字符方法

  • charAt()以单字符字符串的形式返回给指定位置的那个字符
var stringValue = "hello world";
alert(stringValue.charAt(1));   //"e"
  • charCodeAt()以字符编码形式返回指定位置的那个字符
var stringValue = "hello world";
alert(stringValue.charCodeAt(1));   //"101"

2.字符串操作方法

  • concat()
  • slice()
  • substring()
  • substr()

3.字符串位置方法

  • indexOf()从字符串的开头向后搜索子字符串
  • lastIndexOf()从字符串的末尾向前搜索子字符串
var stringValue=" ... ";
var position = new Array();
var pos = stringValue.indexOf("");

while(pos > -1){
position.push(pos);
pos = stringValue.indexOf(""pos+1);
}
alert();

4.trim()
这个方法会创建一个字符串副本,删除前置及后缀的所有空格,返回结果。

5.字符串大小写

  • toLowerCase
  • toLocaleLowerCase
  • toUpperCase
  • toLocaleUppercase

6.字符串的模式匹配方法
match()方法只接受一个参数,要么是一个正则表达式,要么是一个RegExp对象
search()返回字符串中第一个匹配项的索引,无匹配项返回-1
replace()接收两个参数,一个可以是RegExp对象或者一个字符串,第二个参数是一个字符串或者一个函数,

var text = "cat,bat,sat,fat";
var result = text.replace("at","ond");
alert(result); //"cond,bat,sat,fat"

var result = text.replace(/at/g,"ond");
alert(result);//"cond,bond,sond,fond"

split(,)

7.localeCompare()比较两个字符串

如果字符串在字母表中排在字符串参数前返回-1
等于字符串 参数返回0
在字符串参数之后返回1

8.fromCharCode()
接收字符串编码,把他们转换成一个字符串

5.7 单体内置对象

Global

Math
.max
.min
.ceil
.floor
.round
.random

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值