map
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; var s = arr.map(String); console.info(s) function pow(x) { return x * x; } var results = arr.map(pow); console.info(results)
输出如下:
(9) ["1", "2", "3", "4", "5", "6", "7", "8", "9"] (9) [1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce
该函数必须接收两个参数,reduce()累积计算结果继续和序列的下一个元素,其效果如下:
var func = function (x, y) { return x y; } var arr = [1, 3, 5, 7, 9]; var result = arr.reduce(func); console.info(result)
结果是25
filter
和map()不同的是,filter()将传入函数依次作用于每个元素,然后根据返回值true还是false决定保留或丢弃
该元素。
var arr = [1, 2, 4, 5, 6, 9, 10, 15]; var r = arr.filter(function (x) { return x % 2 !== 0; }); console.info(r)
输出如下:
(4) [1, 5, 9, 15]
filter()接收的回调函数,其实可以有多个参数。通常我们仅使用第一个参数,表示Array某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身:
var arr = ['A', 'B', 'C']; var r = arr.filter(function (element, index, self) { console.log(element); // 依次打印'A', 'B', 'C' console.log(index); // 依次打印0, 1, 2 // console.log(self); // self就是变量arr return true; }); console.info(r)
输出如下:
A 0 B 1 C 2 (3) ["A", "B", "C"]
sort
这是因为Array的sort()方法默认把所有元素先转换为String然后排序,结果10排在2之前,因为1字符比2字符好ASCII码小。
var arr = [10, 20, 1, 2]; arr.sort(function (x, y) { if (x < y) { return -1; } if (x > y) { return 1; } return 0; }); console.info(arr)
输出如下:
(4) [1, 2, 10, 20]
sort()方法会直接正确Array修改后,其返回的结果仍然是目前Array
var a1 = ['B', 'A', 'C']; var a2 = a1.sort(); a1; // ['A', 'B', 'C'] a2; // ['A', 'B', 'C'] a1 === a2; // true, a1和a2是同一对象
箭头函数
为什么叫Arrow Function?因为它的定义使用箭头:
x => x * x
上述箭头函数相当于:
function (x) { return x * x; }
我们也可以这样用
// 两个参数: (x, y) => x * x y * y // 无参数: () => 3.14 // 可变参数: (x, y, ...rest) => { var i, sum = x y; for (i=0; i<rest.length; i ) { sum = rest[i]; } return sum; }
若要返回一个对象
x => ({ foo: x })
箭头函数似乎是匿名函数的简写,但事实上,箭头函数和匿名函数有明显的区别:箭头函数内部this由上下文确定的词法作用域。
回顾前面的例子,因为JavaScript函数对this下面的例子无法得到预期的结果:
var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = function () { return new Date().getFullYear() - this.birth; // this指向window或undefined }; return fn(); } }; var ret = obj.getAge() console.info(ret)
结果输出:NaN
var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象 return fn(); } }; var ret = obj.getAge(); console.info(ret)
结果输出:28
class继承
<script> class Student { constructor(name) { this.name = name; } hello() { console.info('Hello, ' this.name '!') } } var xiaoming = new Student(小明); xiaoming.hello(); class PrimaryStudent extends Student { constructor(name, grade) { super(name); // 记得用super调用父类结构方法! this.grade = grade; } myGrade() { console.info('I am at grade ' this.grade) } } var xiaohua = new PrimaryStudent(
小华, 1); xiaohua.myGrade(); </script>
输出如下:
Hello, 小明! I am at grade 1
yield
function* fibonacci() { yield 1; yield 2; return 2; } var it = fibonacci(); console.log(it); // "Generator { }" console.log(it.next()); // 1 console.log(it.next()); // 2 console.log(it.next()); //undefined var itt = fibonacci(); //而且Iterator的return的值不会被for...of循环到 , 它不会被扩展到任何地方 for (var per of itt) { console.info(per) }
输出如下:
fibonacci {<suspended>} {value: 1, done: false} {value: 2, done: false} {value: 2, done: true} 1 2
让我们来看看下面的例子:
function* foo() { yield 0; yield 1; } function* bar() { yield 'x'; yield* foo(); yield 'y'; } for (let v of bar()) { console.log(v); };
输出如下:x 0 1 y