JavaScript数据结构、函数

数据结构

ES6引入了新的数据类型,Map Set等.

Map

同Java Map定义,也是一组键值对结构,查找速度快。
Map的操作:

  • 定义。 var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
  • 增,m.set('Adam', 67) 添加新的key-value
  • 删,m.delete('Adam') 删除key ‘Adam’
  • 改,m.set('Bob', 59) 修改
  • 查,m.has('Adam') 判断是否存在, m.get('Adam') 查询key对应的值

Set

Set 同Java,一组key的集合,但不存储value, key不能重复.

  • 定义。var s = new Set([1, 2, 3, 4]);
  • 增, s.add(5) 添加元素到Set
  • 删, s.delete(3) 删除元素3
  • 改, Set没有改的概念.
  • 查, s.has(3) 查找是否存在3这个元素.

iterabale的遍历

Array Map Set都是iterable类型。

  1. 使用for ... of 遍历,对于Array也支持for ... in, 当Array元素被当作属性值添加使用时,两者有区别,for ... of更符合常规。
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
    console.log(x);
}
for (var x of s) { // 遍历Set
    console.log(x);
}
for (var x of m) { // 遍历Map
    console.log(x[0] + '=' + x[1]);
}
  1. 使用iterable的方法 forEach进行遍历.
    forEach 参数为一个函数。使用如下,
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
    // element: 指向当前元素的值
    // index: 指向当前索引
    // array: 指向Array对象本身
    console.log(element + ', index = ' + index+ ', a='+array);
});

var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
   // Set没有位置的概念,所以第二个参数为 sameElement,与前一个相同
    console.log(element);
});

var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
    // 同理,value相当于值,key相当于位置
    console.log('value='+value+', key='+key);
});

函数

JavaScript函数形式上,跟Java有些不同,没有返回值声明变量类型声明。而且JS中的函数可以像变量一样使用,具有强大的抽象能力。
函数调用对参数匹配也不需要一一对应,例如 可以少于定义声明。
JavaScript有一个参数关键字arguments, 它只在函数内部起作用。使用方法跟Array一样,但它不是Array

注意:JS函数没那么严格

ES6标准引入了rest参数,表示剩余参数的意思。格式function foo(a, b, ...rest) {},rest是一个数组,在这里表示第2个参数以后的参数,如果参数个数<=2 rest为一个空数组,注意不是null

格式如下:

//函数定义,使用 function 表明是一个函数,参数部分只需要写参数名
function abs(x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

//匿名函数,没有函数名
var abs = function (x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
};
//以上,两者的方式是一样的

function sum(...rest) {
   //注意rest不会为null
   var sum = 0;
   for(var i=0; i<rest.length; i++) {
       sum += rest[i];
   }
   return sum;
}

变量作用域

变量的作用域同 java,需要注意的是JavaScripte默认有一个全局对象window,例如常用的alert()都是window的变量。
任何变量(函数也视为变量),如果没有在当前函数作用域中找到,就会继续往上查找,最后如果在全局作用域中也没有找到,才报错。

不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,难以发现。为了减少冲突,可以把自己的所有变量和函数全部绑定到一个全局变量中。起到命名空间的效果,常见的jQuery, YUI, underscore等也是这样实现的,参考示例,

// 唯一的全局变量MYAPP:
var MYAPP = {};

// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;

// 其他函数:
MYAPP.foo = function () {
    return 'foo';
};

ES6引入了关键字let, 为了解决块级作用域的问题,如下,

function foo() {
    var sum = 0;
    //如果使用 var,作用域为整个函数
    for (let i=0; i<100; i++) {
        sum += i;
    }
    // SyntaxError:
    i += 1;
}

解构赋值

从ES6开始支持解构赋值,作用,批量定义变量,并赋值。参考示例,

//传统的赋值
var array = ['hello', 'JavaScript', 'ES6'];
var x = array[0];
var y = array[1];
var z = array[2];

//解构赋值
var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
//以上达到的效果一样

另外,解构赋值也支持对象,使用{...}来对应。使用场景,

//1. 交换两个变量的值
var x=1, y=2;
[x, y] = [y, x]
//2. 用作参数,减少代码量
//hour, minute, second有默认值
function buildDate({year, month, day, hour=0, minute=0, second=0}) {
    return new Date(year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second);
}
buildDate({ year: 2017, month: 1, day: 1 }); // 使用1
buildDate({ year: 2017, month: 1, day: 1, hour: 20, minute: 15 }); //使用2

this

类似于java的this指针,都是用来指向当前对象的,但是在JS中this不能省略(跟java不同),xiaoming.age() age方法中的this为xiaoming.
要保证this指向正确,尽量用obj.xxx()形式调用。

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        var y = new Date().getFullYear();
        return y - this.birth; //this不能省略
    }
};
xiaoming.age; //这是一个方法
xiaoming.age(); //29

可通过apply(obj, array)指定this, 其中obj指定this对象,array 为参数。
使用上相当于Java中的反射,例如,

function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};

xiaoming.age(); // 29
getAge.apply(xiaoming, []); // 29, this指向xiaoming, 参数为空
//也可以用 getAge.call(xiaoming);

另外,还有一个关键字call作用跟apply一样, 只不过call不用封装数据,把参数按顺序传入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值