Javascript程序设计第三版,chapter4-5
第四章 变量、作用域、内存问题
4.1 变量及类型
- 类型检测(typeof:基本类型与instanceof:引用类型)
- typeof检测基本类型:string, number, boolean, undefined, object.
// 使用
var s = 'hello';
var i = 0;
var n = null;
var o = new Object();
alert(s); // string
alert(i); // number
alert(n); // object
alert(o); // object
...
- instanceof检测引用类型,即检测某一对象是哪一种类型的对象,如:对象是否为Array,Regexp,Date,等;
// 使用
alert(p instanceof Object); // p变量是否为Object对象
alert(a instanceof Array); // a变量是否为Array对象
4.2 执行环境与作用域
- Javascript没有块级作用域
即:不像其他类C的语言中,由{……}里面的代码都是块级作用域,作用环境只在括号内。而javascript当中没有块级作用域,所以块级代码中定义的变量会在块级代码执行完毕后,作用域依然存在于全局环境中。
// if、for、等块级代码中定义的变量
for (var i = 0; i < 10 i++)
{
// 块级作用域中的变量
var test = i;
}
// 结果为:10;
// 原因:for中定义的变量,在执行完循环之后依然存在于全局环境中
alert(i);
- 函数中定义的变量,在函数外部不能访问
// 函数中定义的变量作用域只在函数内,函数外不能访问内部变量
// 若要访问,可以参考:闭包;
function scope(a, b)
{
var sum = a + b;
return sum;
}
// 结果:sum is not defined
// 原因:函数外部不能访问内部定义的变量
alert(sum);
第五章 引用类型
Object
创建方式:new与{}
// 任何对象都可以通过new Object()创建
var person = new Object();
var dog = new Object();
// 扩展属性
person.name = "Jack";
person.age = 29;
// 扩展方法
person.walk = function () {alert("person walking"};
/*** 对象字面量创建对象 ***/
var person = {
name: "jack",
age: 29
walk: function(){alert("walking")}
};
Array
// 空数组
var a1 = new Array();
// 指定个数的(实际js中数据长度是可变的)
var a2 = new Array(3);
// 创建,初始化
var a3 = new Array("John", "Jack", "Tom");
数组字面量定义方式
// 空数组
var b1 = [];
// 指定内容
var b2 = ["red", "black", "gray"];
// 切记不要使用多个逗号,而之间没任何成员
var b3 = [,,,,,,]; // 会创建含有七个成员的数组,但实际是没有内容的,尽量不要这么做
// 数组长度,可变,可赋值
// b2数组的长度就变成了10,且下标3-9的成员都是未定义undefined,没有具体值
b2.length = 10;
检查对象是否为数组方法:instanceof Array或者Array.isArray()方法
- instanceof使用前提:假设只有一个全局作用域;
- Array.isArray(obj):与在哪个全局作用域无关
转换方法
- toLocaleString():数组值的以逗号隔开的字符串
- toString():数组转化成以逗号隔开的字符串
- valueOf():返回的依旧是数组
- join():指定分隔符来返回数组字符串,不传值时默认用逗号
数组栈(后进先出LIFO,push+shift)和队列(先进先出FIFO,pop+unshift)方法
- push:尾部添加
- pop:尾部删除
- shift:头部删除
- unshift:头部添加
重排序方法
- sort:默认以字符串比较,如果需要进行数值比较,需要给其传入一个比较函数
function compare(a, b) { // 升序排列 if (a < b) return -1; else if (a > b) return 1; else return 0; // 降序排列 if (a < b) return 1; else if (a > b) return -1; else return 0; } // 简化 function compare(a, b) { // 直接以0作为界限 return a - b; }
- reverse:反转数组
其他数组处理函数
- concat:追加数组,会另外复制一份数组返回,源数组无影响
var a = ['a1', 'a2', 'a3']; var b = a.concat('b1', ['c1', 'c2']); // b 的输出结果为连结后的新数组,a不变 alert(b); // ==> a1,a2,a3,b1,c1,c2
slice:截取数组,只有一个参数时从该处开始直到数组结尾进行截取返回;有两个参数(index, count)时,表示从下标为index开始截取count个成员,组成新的数组返回,源数组不变。
var a = [1, 2, 3, 4, 5, 6, 7, 8]; var b1 = a.slice(3); // 结果:4,5,6,7,8 var b2 = a.slice(3, 2); // 结果:4,5
splice:该方法有多个功能,会根据参数的不同实现,删除,插入,替换功能,返回结果都是从源数组中删除的项
- 删除:只指定两个参数splice(start, count);
- 插入:至少指定三个参数splice(start, 0, value1, value2, …); start指定插入的位置, 0:表示要删除的项,不为0时可以同时实现替换,value1, value2, …表示要插入的数据;
- 替换:至少三个参数splice(start, count, value1, value2, …); start需要替换的起始位置,count删除这么多项,然后插入value1, value2, …实现原理和插入一样;
indexOf(左->右)和lastIndexOf(右->左):查找指定项的位置,接受的参数有两个(value, [start]), value:需要查找的值,start:从哪里开始查找;没找到返回-1
// 两个方法查找时进行比较都是采用“===”全等
var a = [1, 2, 3, 4, 5, 6, 5, 8, 10, 2, 1];
var b1 = a.indexOf(3, 0); // 从左->右查找第一个3,从下标0开始
var b2 = a.lastIndexOf(3, 0); // 从右到左查找第一个3,从最后一个开始
var c1 = a.indexOf(5, 5); // 6
var c2 = a.lastIndexOf(5, 5); // 4
迭代方法:循环遍历数组,用指定函数条件来判断数组内的元素是否符合条件, 使用方法(every也可以是:some, filter, forEach, map):
array.every(function(item, index, array){return item > 2})
every:数组中每个成员都满足function里的条件;
var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1]; var everyResult = numbers.every(function(item, index, array){ return item > 2});
filter:过滤出符合function里条件的成员,组成新数组返回;
var filterResult = numbers.filter(function(item, index, array){ return item > 2}); // => [3, 4, 5, 4, 3]
forEach:没有返回值,作用只用于遍历数组中每一项,并针对每一项作出相应的操作;
numbers.forEach(function(item, index, array){ //执行一定操作 }); // 只做遍历,然后在函数中处理,无返回值
some:只要有满足条件的,就返回true;
var someResult = numbers.some(function(item, index, array){ return item > 2}); // 返回boolean值,只要有一个满足条件就返回true
map:对每个成员进行操作之后,重新组成新的数组返回;
var mapResult = numbers.map(function(item, index, array){ return item * 2}); // 即:将每个成员乘2之后组成新的数组返回
归并方法(reduce和reduceRight):递归调用,处理函数的返回值作为自身的第一个参数传入;reduce是从左到右遍历,reduceRight是从右到左遍历;
var arr = [1, 2, 3, 4, 5];
var sum = arr.reduce(function(prev, cur, index, array){
// 返回的值传递给了prev,递归下去直到数组遍历结束
return prev + cur;
});
// reduceRight用法和reduce一样