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.

new object returned

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

1

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学习总结(八)正则表达式

0 0