JavaScript深入二
来源:互联网 发布:软件开发入门 编辑:程序博客网 时间:2024/06/06 10:43
JavaScript深入浅出二
数组
数组是值的有序集合。每个值叫做元素,每个元素在数组中都有数字位置编号,也就是索引。JS中的数组是弱类型的,数组中可以含有不同类型的元素。数组元素甚至可以是对象或其它数组。
基本
创建数组
1.字面量的方式
var commasArr1 = [1, , 2]; // 1, undefined, 2var commasArr2 = [,,]; // undefined * 2
2.new Array
方式
var arr = new Array(); var arrWithLength = new Array(100); // undefined * 100var arrLikesLiteral = new Array(true, false, null, 1, 2, "hi");// 等价于[true, false, null, 1, 2, "hi"];
上面的代码,不使用new
关键字也行
数组元素读写
可以动态的添加一个元素,如下,最开始创建的时候arr只有5个元素,我们可以通过arr[5] = 6;
添加一个元素。
var arr = [1, 2, 3, 4, 5];arr[5] = 6;arr.length; // 6
通过delete
删除一个元素,其实是将对应的数组内容置为undefined
delete arr[0];arr[0]; // undefineddelete arr[2];arr; // [0, 1, undefined, 3, 4]arr.length; // 52 in arr; // false
数组元素增删
需要注意到的一点是,JavaScript中的数组是动态的,无需指定大小 push
在尾部添加数组元素
var arr = [];arr[0] = 1;arr[1] = 2;arr.push(3);arr; // [1, 2, 3]arr[arr.length] = 4; // equal to arr.push(4);arr; // [1, 2, 3, 4]
如果想在数组的头部去添加,使用unshift
arr.unshift(0);arr; // [0, 1, 2, 3, 4];
可通过arr.length -= 1;
移除最后一个元素
arr.length -= 1;arr; // [0, 1, undefined, 3, 4], 4 is removed
使用pop
方法删除数组最尾部的元素
arr.pop(); // 3 returned by poparr; // [0, 1, undefined], 3 is removed
shift
在数组的头部删除元素
arr.shift(); // 0 returned by shiftarr; // [1, undefined]
数组迭代
需要注意的是for-in
迭代并不保证数组的顺序
稀疏数组
稀疏数组并不含有从0开始的连续索引。一般length属性值比实际元素个数大。
var arr1 = [undefined];var arr2 = new Array(1);0 in arr1; // true0 in arr2; // falsearr1.length = 100;arr1[99] = 123;99 in arr1; // true98 in arr1; // falsevar arr = [,,];0 in arr; // false
数组方法
一般的对象都有一个原型指向Object.prototype
,所以对象可以调用很多的方法
同样数组对象也有原型Array.prototype
,提供了大量的方法,对数组进行操作。
1.Array.prototype.join
将数组转为字符串
var arr = [1, 2, 3];arr.join(); // "1,2,3"arr.join("_"); // "1_2_3"function repeatString(str, n) { return new Array(n + 1).join(str);}repeatString("a", 3); // "aaa"repeatString("Hi", 5); // "HiHiHiHiHi"
2.Array.prototype.reverse
把一个数组逆序
注意会对原数组进行修改
var arr = [1, 2, 3];arr.reverse(); // [3, 2, 1]arr; // [3, 2, 1]
3.Array.prototype.sort
排序
默认按字母的顺序排序
var arr = ["a", "d", "c", "b"];arr.sort(); // ["a", "b", "c", "d"]arr = [13, 24, 51, 3];arr.sort(); // [13, 24, 3, 51]arr; // [13, 24, 3, 51]
注意原数组被修改
如何按数字大小排序?
arr.sort(function(a, b) { return a - b;}); // [3, 13, 24, 51]arr = [{age : 25}, {age : 39}, {age : 99}];arr.sort(function(a, b) { return a.age - b.age;});arr.forEach(function(item) { console.log('age', item.age);});// result:// age 25// age 39// age 99
4.Array.prototype.concat
数组合并
var arr = [1, 2, 3];arr.concat(4, 5); // [1, 2, 3, 4, 5]arr; // [1, 2, 3]arr.concat([10, 11], 13); // [1, 2, 3, 10, 11, 13]arr.concat([1, [2, 3]]); // [1, 2, 3, 1, [2, 3]]
注意原数组并没有被修改
5.Array.prototype.slice
返回部分数组
var arr = [1, 2, 3, 4, 5];arr.slice(1, 3); // [2, 3]arr.slice(1); // [2, 3, 4, 5]arr.slice(1, -1); // [2, 3, 4]arr.slice(-4, -3); // [2]
注意原数组并没有被修改
6.Array.prototype.splice
对数组进行拼接
不仅可以删除一些元素,还可以添加一些元素
var arr = [1, 2, 3, 4, 5];arr.splice(2); // returns [3, 4, 5]arr; // [1, 2];arr = [1, 2, 3, 4, 5];arr.splice(2, 2); // returns [3, 4]arr; // [1, 2, 5];arr = [1, 2, 3, 4, 5];arr.splice(1, 1, 'a', 'b'); // returns [2]arr; // [1, "a", "b", 3, 4, 5]
注意原数组被修改
arrayObject.splice(index,howmany,item1,.....,itemX)
- index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
- howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
- item1, …, itemX 可选。向数组添加的新项目。
7.Array.prototype.forEach
数组遍历
var arr = [1, 2, 3, 4, 5];arr.forEach(function(x, index, a){ console.log(x + '|' + index + '|' + (a === arr));});// 1|0|true// 2|1|true// 3|2|true// 4|3|true// 5|4|true
a
指向数组本身
8.Array.prototype.map
对数组做一些映射
var arr = [1, 2, 3];arr.map(function(x) { return x + 10;}); // [11, 12, 13]arr; // [1, 2, 3]
注意原数组并未被修改
9.Array.prototype.filter
数组过滤
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];arr.filter(function(x, index) { return index % 3 === 0 || x >= 8;}); // returns [1, 4, 7, 8, 9, 10]arr; // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
注意原数组并未被修改
10.Array.prototype.every & some
对数组进行判断
例如想检测下数组是不是都是小于10的
var arr = [1, 2, 3, 4, 5];arr.every(function(x) { return x < 10;}); // truearr.every(function(x) { return x < 3;}); // false
every
表示的是每一个元素都符合某个条件 some
表示的是只要是任意一个元素符合某个条件
var arr = [1, 2, 3, 4, 5];arr.some(function(x) { return x === 3;}); // truearr.some(function(x) { return x === 100;}); // false
11.Array.prototype.reduce&reduceRight
把数组聚合成某一个结果,例如两个两个相加,两个两个相乘
var arr = [1, 2, 3];var sum = arr.reduce(function(x, y) { return x + y}, 0); // 6arr; //[1, 2, 3]arr = [3, 9, 6];var max = arr.reduce(function(x, y) { console.log(x + "|" + y); return x > y ? x : y;});// 3|9// 9|6max; // 9max = arr.reduceRight(function(x, y) { console.log(x + "|" + y); return x > y ? x : y;});// 6|9// 9|3max; // 9
12.Array.prototype.indexOf&lastIndexOf
数组检索
var arr = [1, 2, 3, 2, 1];arr.indexOf(2); // 1arr.indexOf(99); // -1arr.indexOf(1, 1); // 4arr.indexOf(1, -3); // 4arr.indexOf(2, -1); // -1arr.lastIndexOf(2); // 3arr.lastIndexOf(2, -2); // 3arr.lastIndexOf(2, -3); // 1
13.Array.isArray
判断是否为数组
需要注意的是Array.isArray
不是prototype
上的方法
Array.isArray([]); // true[] instanceof Array; // true({}).toString.apply([]) === '[object Array]'; // true[].constructor === Array; // true
函数
JS中函数也是对象,所以JS函数可以像其它对象那样操作和传递,所以JS的函数也叫函数对象
函数没有返回值的话,默认返回一个undefined
函数的调用方式:
- 直接调用
foo()
- 对象方法
o.method()
- 构造器
new Foo()
- call/applybind
func.call(o)
函数调用方式
方法调用模式
当一个函数被保存为对象的一个属性时,称它为一个方法。当一个方法被调用时,this被绑定到该对象
var obj = { value: 0, increment: function() { this.value+=1; }};obj.increment(); //方法调用
在上面的例子中,this
被绑定到obj
函数调用模式
当函数并非一个对象的属性时,它被当做一个函数来调用
在此模式下,this
被绑定到全局对象。这是JavaScript语言设计上的一个错误,盲目的把this绑定到全局对象,可能会破坏它的当前上下文,如下的例子:
var value = 500; //全局变量var obj = { value: 0, increment: function() { this.value++; var innerFunction = function() { alert(this.value); } innerFunction(); //函数调用模式 }}obj.increment(); //方法调用模式
obj.increment();
方法调用,提示的值是500
,表示当前this
被绑定到全局对象
幸运的是,有一个很容易的解决方法:
var value = 500; //全局变量var obj = { value: 0, increment: function() { var that = this;//解决方法 that.value++; var innerFunction = function() { alert(that.value); } innerFunction(); //函数调用模式 }}obj.increment();
构造器调用模式
如果在一个函数前面带上new
来调用,那么背地里将会创建一个连接到该函数的prototype
成员的新对象,同时this
会被绑定到那个新的对象上
//创建一个名为Quo的构造器函数,它构造一个带有status属性的对象var Quo = function(string){ this.status = string;}//给Quo的所有实例提供一个名为get_status的公共方法Quo.prototype.get_status = function () { return this.status;};// 构造一个 Quo 的实例var myQuo = new Quo('success');console.log(myQuo.get_status()); // success
一个函数,如果创建的目的就是希望结合new前缀来调用,那它就被称为构造器函数,按照约定,它们保存在大写格式命名的变量里
new前缀也会改变return语句的行为:
1.如果函数返回一个简单类型(number, string, boolean, null 或者 undefined),则返回值将被忽略,直接返回this
。
2.如果该函数返回Object的一个实例(除简单类型之外的任何其他实例),那么将返回该对象而不是返回this。这种模式并不经常使用,但是在与闭包一起使用时可能有用。
var Cheese = function(type) { var cheeseType = type; return cheeseType;}cheddar = new Cheese("cheddar"); //new object returned, not the type.
var obj = { data : "Hello World"}var Func1 = function() { return obj;}var Func2 = function() { return "I am a simple type";}var f1 = new Func1(); //f1 is set to objvar f2 = new Func2(); //f2 is set to a new object
Apply调用模式
apply方法让我们构建一个参数数组传递给调用函数。它也允许我们选择this值。apply方法接收两个参数,第一个是绑定给this的值,第二个就是一个参数数组
var add = function(num1, num2) { return num1+num2;}array = [3,4];add.apply(null,array); //7var obj = { data:'Hello World'}var displayData = function() { alert(this.data);}displayData(); //undefineddisplayData.apply(obj); //Hello World
创建函数的方式
声明式
function add(a, b){ a = +a; b = +b; if (isNaN(a) || isNaN(b)) { return; } return a + b;}
函数表达式
在函数表达式存储在变量后,变量也可作为一个函数使用:
var x = function (a, b) {return a * b};var z = x(4, 3);
以上函数实际上是一个 匿名函数 (函数没有名称)。
函数存储在变量中,不需要函数名称,通常通过变量名来调用。
还有一种方式是,把一个匿名的函数用括号括起来,然后直接调用,被称为自执行匿名函数
(function () {})();
自执行匿名函数的作用:
- 可以用它创建命名空间,只要把自己所有的代码都写在这个特殊的函数包装内,那么外部就不能访问,除非你允许(变量前加上window,这样该函数或变量就成为全局)。各JavaScript库的代码也基本是这种组织形式
也可以将函数对象作为返回值
return function(){};
还有一种形式,非匿名函数,命名函数表达式(NFE)
var add = function foo(a, b){}
Function表达式
var func = new Function('a', 'b', 'console.log(a+b)');func(1,2);
this
在浏览器中,全局对象this
指的是window
console.log(this === window)//true
函数属性&arguments
如下的函数:
function foo(x,y,z){ arguments.length//2 arguments[0]//1 arguments[0] = 10 x//change to 10 arguments[2] = 100 z//still undefined arguments.callee === foo//true}foo(1,2);
foo.length//3
形参个数 foo.name//"foo"
函数名 arguments.length
-实参个数
arguments
是类数组对象
正则表达式
参考JavaScript学习总结(八)正则表达式
- JavaScript深入二
- 深入javascript function对象(二)
- javascript深入学习之二
- 深入理解javascript闭包(二)
- 深入JavaScript(二)之解析机制
- JavaScript专题(二):深入理解iframe
- JavaScript专题(二):深入理解iframe
- 深入理解javascript闭包(二)
- 深入JavaScript(二)之解析机制
- 深入理解javascript闭包(二)
- JavaScript专题(二):深入理解iframe
- 深入理解JavaScript系列(二): 原型、原型链与继承
- javaScript笔记(二十二) 事件绑定及深入
- [译文]深入理解JavaScript的this关键字(二)
- 深入JavaScript
- JavaScript深入
- 深入javascript
- 深入JavaScript
- 算法导论程序6--随机算法(Python)
- 每天一个Linux命令:mkdir
- Oracle日期查询:季度、月份、星期等时间信息
- 从965到996,传统IT业到互联网
- STM32F10x的启动汇编分析
- JavaScript深入二
- 1.8地址总线
- 1.9数据总线
- xcode格式
- mac os 安装brew
- 1.10控制总线
- Spring data jpa HQL @Query 自定义查询及更新删除 及 sql写法
- 检测点1.1
- 每日一句:Love