第5章:引用类型

导读:

  • 使用对象
  • 创建并操作数组
  • 理解基本的JavaScript类型
  • 使用基本类型和基本包装类型

引用类型、对象、函数的关系

  • 引用类型是一种数据结构,将数据和功能组织在一起。
  • 对象是某个引用类型的实例。
  • 对象是new+构造函数创建而成。(构造函数本身就是一个函数,可以传参,Object类型,Array类型,Date类型)

一、Object类型

创建Object实例的两种方式

  1. new+Object构造函数
var peerson = new Object();
person.name = "zwh";
person.age = 18;
var person = {
    name : "zwh",
    age : 18
};
var person = {};    //与new Object()相同
person.name = "zwh";
person.age = 18;

对象字面量好处是简单易读,而且可以向函数传参

function displayInfo(args){
    var output = "";
    if(typeof args.name == "string"){
        output += "Name:" + args.name + "\n";
    }
    if(typeof args.age == "number"){
        output += "Age:" + args.age+ "\n";
    }
    alert(output);
}

displayInfo({
    name : "zwh",
    age : 18
});
displayInfo({
    name : "zw"
});

访问对象属性的两种方法
1.点表示法(推荐)

alert(person.name);    //"zwh"

2.方括号表示法

alert(person["name"]);    //"zwh"

方括号表示法可以通过变量来访问属性,或者属性名有特殊字符和关键字

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

person["first name"] = "zwh";

二、Array类型

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

创建数组的两种方式

  1. new+Array构造函数(new可省略)
var colors = new Array();
var colors = Array();
var colors = new Array(20);    //length20,undefined
var colors = new Array("red", "blue", "green");

2.数组字面量表示法

var colors = ["red", "blue", "green"];    //创建一个包含3个字符串的数组
var names = [];    //创建一个空数组
var values = [1 , 2 , ]    //不要这样!这样会创建一个包含2或3项的数组(浏览器差异)

读取和设置数组的值

array[array.length];

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

length属性的特点

可设置,可以从数组末尾移除项或增加新项

var colors = ["red", "blue", "green"];    //创建一个包含3个字符串的数组
alert(colors.length);    //3
colors.length = 2;
alert(colors[2]);    //undefined

var colors = ["red", "blue", "green"];    //创建一个包含3个字符串的数组
alert(colors.length);    //3
colors.length = 4;
alert(colors[3]);    //undefined
var colors = ["red", "blue", "green"]    //创建一个包含3个字符串的数组
colors[colors.length] = "black";     //(在位置3)添加一种颜色
colors[colors.length] = "brown";   //(在位置4)再添加一种颜色

检测数组

Array.isArray([1, 2, 3]); // true

5.2.2转换方法

toString()方法返回由数组中的每个值的字符串拼接而成的一个以逗号分隔的字符串
join()方法调用的是toString()方法
valueOf()方法返回的还是数组

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

5.2.3栈方法

添加:末尾push(),返回更新数组长度
移除:末尾pop(),返回移除的项

var colors = new Array();
var count = colors.push("red", "green");    //添加两项
alert(count);    //2

var item = colors.pop();    //移除末尾一项
alert(item);    //"black"    //返回移除的项

5.2.4队列方法

添加:头部unshift(),返回更新数组长度
移除:头部shift(),返回移除的项

var colors = new Array();
var count = colors.unshift("red", "green");    //添加两项
alert(count);    //2

var item = colors.shift();    //移除头部一项
alert(item);    //"black"    //返回移除的项

5.2.5重排序方法

  1. 数组反转排序 reverse()
var values = [1, 2, 3, 4, 5];
values.reverse();
alert(values);    //5,4,3,2,1
  1. sort()方法会调用每个数组项的toString()转型方法,比较的是字符串。
    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

function compare(value1,value2){    //等价于
    return value2 - value1;
}

5.2.6操作方法

concat():创建新数组,接收一个或多个数组作为参数,添加到新数组的末尾

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

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

slice():创建新数组,接收一个或两个参数,返回起始和结束位置之间的项(不包括结束位置的项,-1),

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(colors2);    //green,blue,yellow

splice()方法接收两个或三个参数,返回删除的项组成的数组(如无删除,则返回空数组)

  • splice(起始位置,要删除的项,要插入的项)
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开始插入两项
alert(colors);    //green,yellow,orange,blue
alert(removed);    //返回一个空数组

removed = colors.splice(1, 1, "red", "purple");    //删除一项,插入两项
alert(colors);    //green,red,purple,orange,blue
alert(removed);    //yellow

位置方式
indexOf(),lastIndexOf(),接收两个参数,要查找的项起点位置(可选),返回要查找的项在数组中的位置,没找到则返回-1(全等操作符===)。
indexOf()从数组的开头(位置0)开始向后查找,lastIndexOf()从数组末尾开始向前查找。

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

alert(numbers.indexOf(4, 4));    //5
alert(numbers.lastIndexOf(4, 4));    //3

5.2.8 五种迭代方法

方法接收两个参数:要在每一项运行的函数和运行该函数的作用域对象(影响this的值)。传入这些方法中的函数会接收三个参数:数组项的值该项在数组中的位置数组对象本身

  • every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。【等同于&&】
  • some():对数组中的每一项运行给定函数,如果该函数对任一项都返回true,则返回true。【等同于||】
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
  • filter():对数组中的每一项运行给定函数,返回该函数会返回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]
  • map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。【加工数组,用于创建一一对应的数组】
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]
  • forEach():对数组中的每一项运行给定函数,没有返回值。【根据数据源执行任务】
var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item,index,array){
    //执行某些任务
});

5.2.9 缩小方法

reduce(),reduceRight()
接收两个参数:在每一项上调用的函数作为缩小基础的初始值(可选)。函数接收4个参数:前一个值当前值项的索引数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数就是数组的第二项。

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev,cur,index,array){
    return prev + cur;
});
alert(sun);    //15
//第一次执行回调函数,prev是1,cur是2。第二次,prev是3(1加2的结果),cur是3。
//reduceRight()方向相反,第一次prev是5,cur是4。

5.3 Date类型

创建当前日期和时间对象
var now = new Date();

创建特定日期和时间对象的两种方法
1.Date.parse()

var someDate = new Date(Date.parse("May 25, 2004"));
//2004年5月25日(浏览器差异)

//等价于
var someDate = new Date("May 25, 2004");

2.Date.UTC()(推荐)
年份(必填),月份(必填,0计数),日期,小时,分钟,秒数

var y2k = new Date(Date.UTC(2000,0)); 
//GMT时间2000年1月1日0时

var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55));
 //GMT时间2005年5月5日下午5:55:55

Data.now()方法返回调用这个方法时的日期和时间的毫秒数,可用于分析代码工作

//取得开始时间
varr start = Date.now();

//调用函数
doSomething();

//取得停止时间
var stop = Date.now();
var result = stop - start;

Date类型会调用valueOf()方法,返回日期的毫秒数。可直接用于比较日期值

var date1 = new Date(2007, 0, 1);
var date1 = new Date(2007, 1, 1);

alert(date1 < date2);    //true
alert(date1 > date2);    //false

Date 对象方法

方法 描述
getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。
getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6)。
getFullYear() 从 Date 对象以四位数字返回年份。
getHours() 返回 Date 对象的小时 (0 ~ 23)。
getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。
getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。
getMonth() 从 Date 对象返回月份 (0 ~ 11)。
getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。
getTime() 返回 1970 年 1 月 1 日至今的毫秒数。
getTimezoneOffset() 返回本地时间与格林威治标准时间 (GMT) 的分钟差。
getUTCDate() 根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。
getUTCDay() 根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。
getUTCFullYear() 根据世界时从 Date 对象返回四位数的年份。
getUTCHours() 根据世界时返回 Date 对象的小时 (0 ~ 23)。
getUTCMilliseconds() 根据世界时返回 Date 对象的毫秒(0 ~ 999)。
getUTCMinutes() 根据世界时返回 Date 对象的分钟 (0 ~ 59)。
getUTCMonth() 根据世界时从 Date 对象返回月份 (0 ~ 11)。
getUTCSeconds() 根据世界时返回 Date 对象的秒钟 (0 ~ 59)。
getYear() 已废弃。请使用 getFullYear() 方法代替。
parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。
setDate() 设置 Date 对象中月的某一天 (1 ~ 31)。
setFullYear() 设置 Date 对象中的年份(四位数字)。
setHours() 设置 Date 对象中的小时 (0 ~ 23)。
setMilliseconds() 设置 Date 对象中的毫秒 (0 ~ 999)。
setMinutes() 设置 Date 对象中的分钟 (0 ~ 59)。
setMonth() 设置 Date 对象中月份 (0 ~ 11)。
setSeconds() 设置 Date 对象中的秒钟 (0 ~ 59)。
setTime() setTime() 方法以毫秒设置 Date 对象。
setUTCDate() 根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。
setUTCFullYear() 根据世界时设置 Date 对象中的年份(四位数字)。
setUTCHours() 根据世界时设置 Date 对象中的小时 (0 ~ 23)。
setUTCMilliseconds() 根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。
setUTCMinutes() 根据世界时设置 Date 对象中的分钟 (0 ~ 59)。
setUTCMonth() 根据世界时设置 Date 对象中的月份 (0 ~ 11)。
setUTCSeconds() setUTCSeconds() 方法用于根据世界时 (UTC) 设置指定时间的秒字段。
setYear() 已废弃。请使用 setFullYear() 方法代替。
toDateString() 把 Date 对象的日期部分转换为字符串。
toGMTString() 已废弃。请使用 toUTCString() 方法代替。
toISOString() 使用 ISO 标准返回字符串的日期格式。
toJSON() 以 JSON 数据格式返回日期字符串。
toLocaleDateString() 根据本地时间格式,把 Date 对象的日期部分转换为字符串。
toLocaleTimeString() 根据本地时间格式,把 Date 对象的时间部分转换为字符串。
toLocaleString() 据本地时间格式,把 Date 对象转换为字符串。
toString() 把 Date 对象转换为字符串。
toTimeString() 把 Date 对象的时间部分转换为字符串。
toUTCString() 根据世界时,把 Date 对象转换为字符串。
UTC() 根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。
valueOf() 返回 Date 对象的原始值。

5.4 RegExp类型

var expression = / pattern / flags ;

  • g:全局模式,即应用于所以字符串,而并非第一个
  • i:不区分大小写模式
  • m:多行模式,即在到达一行文本末尾继续查找下一行

javascript正则表达式

5.5 Function类型

  • 函数是对象的一种,所以函数名实际上也是一个指向函数对象的指针
  • 每个函数都是Function类型的实例,与其他引用类型一样具有属性和方法

函数的主要两种定义方式

//函数声明定义
function sum(num1,num2){
    return num1 + num2;
}

//函数表达式定义
var sum = function(num1,num2){
    return num1 + num2;
};    //末尾有分号
//函数的第三种定义方式:Function构造函数(不推荐,代码会解析两次)
var sum =new Function("num1", "num2", "return num1 + num2");

5.5.1 没有重载

函数名实际上是一个指向函数对象的指针

function addSomeNumber(num){
    return num + 100;
}
function addSomeNumber(num){
    return num + 200;
}

var result = addSomeNumber(100)    //300

5.5.2 函数声明与函数表达式

解析器在向执行环境中加载数据时,解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);函数表达式必须等到解析器执行到它所在的代码行,才会真正被执行。

//函数声明
alert(sum(10,10));
function sum(num1,num2){
    return num1 + num2;
}

//函数表达式
alert(sum(10,10));    //报错!!
var sum = function(num1,num2){
    return num1 + num2;
}

5.5.3 作为值的函数

函数名本身就是变量,所以也函数可以作为值来使用。
不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回。


//传递参数
function add10(num){
    return num + 10;
}
var result = callSomeFunction(add10, 10);
alert(result);    //20

函数作为另一个函数的结果返回
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;
        }
    };
}    //根据某个对象属性对数组排序

var date = [{name: "zwh", age: 28}, {name: "nw", age: 29}]

data.sort(createComparisonFunction("name"));
alert(data[0].name);    //nw

data.sort(createComparisonFunction("age"));
alert(data[0].name);    //28

5.5.4 函数内部属性

  • arguments.callee属性,指向此arguments对象的函数
//经典阶乘函数
function factorial(num){
    if(num <= 1){
        return 1;
    }else{
        return num * factorial(num-1)
    }
}

//用arguments.callee属性消除factorial函数名耦合
function factorial(num){
    if(num <= 1){
        return 1;
    }else{
        return num * arguments.callee(num-1)
        //return num * factorial(num-1)
    }
}

var trueFactorrial = factorial;
factorial = function(){
    return 0;
};
alert(trueFactorial(5));    //120
alert(factorial(5));    //0
  • this引用的是函数的环境对象
windows.color = "red";
var o = {color: "blue"};

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

sayColor();    //red

o.sayColor = sayColor;
o.sayColor();    //blue
  • caller,这个属性保存着调用当前函数的函数的引用(如果是在全局作用域中调用
    当前函数,则值为null)
function outer(){
    inner();
}

function inner(){
    alert(inner.caller);
}

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

//等同于
function outer(){
    inner();
}

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

outer();
  • apply()方法,用于在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组(也可以arguments对象)。
function sum(num1, num2){
    return num1 +num2;
}
function callSum1(num1, num2){
    return sum.appply(this, arguments);
}
function callSum2(num1, num2){
    return sum.apply(this, [num1, num2]);
}

alert(callSum1(10,10))    //20
alert(callSum2(10,10))    //20
  • call()方法,用于在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。apply()方法接收两个以上参数:一个是在其中运行函数的作用域,其他是运行的参数。
function sum(num1, num2){
    return num1 + num2;
}
function callSum(num1, num2){
    return sum.call(this, num1, num2);
}
alert(callSum(10,10));    //20

apply()方法与call()方法区别:call()方法必须明确地传入每一个参数。使用call()还是apply(),完全取决于你采取哪种传参方式最方便。不需传参的情况下,哪种方法都无所谓。

apply()和call()真正强大的地方,是能扩充函数赖于运行的作用域,避免对象和方法的耦合关系。

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

sayColor();    //red

sayColor.call(this);    //red
sayColor.call(window);    //red
sayColor.call(o);    //blue
  • bind()方法,会创建并返回一个函数实例,其this值会被绑定到传给bind()函数的值
window.color = "red";
var o = {color: "blue"};
function sayColor(){
    alert(this.color);
}

var objectSayColor = sayColor.bind(o);
objectSayColor();    //blue,this等于o

5.6.2 Number类型

  • toString()方法,接收一个参数,返回几进制的字符串
var num = 10;
alert(num.toString());    //"10"
alert(num.toString(2));    //"1010"
alert(num.toString(8));    //"12"
alert(num.toString(10));    //"10"
alert(num.toString(16));    //"a"
  • toFixed()方法,按照指定的小数位返回数值的字符串,适合处理货币值
var num = 10;
alert(num.toFixed(2));    //"10.00"
  • toExponential()方法,按照指定的小数位指数返回数值的字符串
var num = 10;
alert(num.toExponential(1));    //"1.0e+1"

5.6.3 String类型

  • length属性,表示字符串包含多少个字符
var stringValue = "hello world";
alert(stringValue);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • 引用类型的值(对象)是引用类型的一个实例,在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在...
    Elevens_regret阅读 344评论 0 0
  • 1.Object类型 1)创建Object实例的方式: 使用字面量创建 使用Object创建 使用构造函数创建 使...
    Ching_Lee阅读 248评论 0 0
  •   引用类型的值(对象)是引用类型的一个实例。   在 ECMAscript 中,引用类型是一种数据结构,用于将数...
    霜天晓阅读 1,054评论 0 1
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,233评论 0 4
  • 据全民星探app独家报道的张铁林私生女的新闻引起广泛关注,私生女张某和母亲侯女士即将起诉,已准备与张铁林对簿公堂,...
    蓝传说阅读 327评论 0 0