函数的扩展

// function log(x, y = 'World') {
// console.log(x, y);
// }

// log('Hello') // Hello World
// log('Hello', 'China') // Hello China
// log('Hello', '') // Hello

// function Point(x = 0, y = 0) {
// this.x = x;
// this.y = y;
// }

// var p = new Point();
// console.log(p) // { x: 0, y: 0 }

// function foo({x, y = 5}) {
// console.log(x, y);
// }

// foo({}) // undefined, 5
// foo({x: 1}) // 1, 5
// foo({x: 1, y: 2}) // 1, 2
// //foo() // TypeError: Cannot read property 'x' of undefined

// function fetch(url, { body = '', method = 'GET', headers = {} }) {
// console.log(url);//http://example.com
// console.log(method);//GET
// }

// fetch('http://example.com', {})
// "GET"

//fetch('http://example.com')//不能忽略第二个参数
// 报错

// 写法一
// function m1({x = 0, y = 0} = {}) {
// return [x, y];
// }

// // 写法二
// function m2({x, y} = { x: 0, y: 0 }) {
// return [x, y];
// }

// // 函数没有参数的情况
// m1() // [0, 0]
// m2() // [0, 0]

// // x和y都有值的情况
// m1({x: 3, y: 8}) // [3, 8]
// m2({x: 3, y: 8}) // [3, 8]

// // x有值,y无值的情况
// m1({x: 3}) // [3, 0] {x: 3}生效,所以不等于空对象,也就是x为3,y有默认值0;
// m2({x: 3}) // [3, undefined] {x: 3}生效,取代默认对象{ x: 0, y: 0 },也就是说x=3,而y没有定义

// // x和y都无值的情况
// m1({}) // [0, 0]; 等于空对象,所以取默认值
// m2({}) // [undefined, undefined] //等于空对象。取代默认对象{ x: 0, y: 0 } x和y没有定义

// m1({z: 3}) // [0, 0] 取默认值
// m2({z: 3}) // [undefined, undefined] 取代空对象,x和y都没有定义

// var x = 1;

// function f(x, y = x) {
// console.log(y);
// }
// f()//undefined
// f(2) // 2


// let x = 1;//如果此时,全局变量x不存在,就会报错。

// function f(y = x) {//x指向的是全局
// let x = 2;
// console.log(y);
// }

// f() // 1


// // 由于在函数作用域中,存在变量x,但是默认值在x赋值之前先执行了,所以这时属于暂时性死区(参见《let和const命令》一章),任何对x的操作都会报错。
// var x = 1;

// function foo(x = x) {
// // ...
// }

// foo() // ReferenceError: x is not defined

// 如果参数的默认值是一个函数,该函数的作用域是其声明时所在的作用域。
// let foo = 'outer';

// function bar(func = () => foo) {
// let foo = 'inner';
// console.log(func()); // outer
// }

// bar();

// 如果这样写就报错
// function bar(func = () => foo) {
// let foo = 'inner';
// console.log(func());
// }

// bar() // ReferenceError: foo is not defined

// var x = 1;
// function foo(x, y = function() { x = 2; }) {
// var x = 3;
// y();
// console.log(x);
// }

// foo() // 3
// 函数foo的参数y的默认值是一个匿名函数。函数foo调用时,它的参数x的值为undefined,所以y函数内部的x一开始是undefined,后来被重新赋值2。但是,函数foo内部重新声明了一个x,值为3,这两个x是不一样的,互相不产生影响,因此最后输出3。

// function throwIfMissing() {
// throw new Error('Missing parameter');
// }

// function foo(mustBeProvided = throwIfMissing()) {
// return mustBeProvided;
// }

// foo()
// // Error: Missing parameter

// ES6引入rest参数(形式为“...变量名”)

// function add(...values) {
// let sum = 0;

// for (var val of values) {
// sum += val;
// }

// return sum;
// }

// console.log(add(2, 5, 3)) // 10

// 函数的length属性,不包括rest参数。

// 扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。

// // es6的合并数组
// var arr1 = ['a', 'b'];
// var arr2 = ['c'];
// var arr3 = ['d', 'e'];
// var arr4 = [...arr1, ...arr2, ...arr3];
// console.log(arr4)// [ 'a', 'b', 'c', 'd', 'e' ]

// let map = new Map([
// [1, 'one'],
// [2, 'two'],
// [3, 'three'],
// ]);

// let arr = [...map.keys()]; // [1, 2, 3]
// console.log(arr);

// let arr2 =[...map.values()];
// console.log(arr2);[ 'one', 'two', 'three' ];

// let arr3 =[...map.entries()];
// console.log(arr3)

// 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。
// 箭头函数有几个使用注意点。

// (1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

// (2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

// (3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。

// (4)不可以使用yield命令,因此箭头函数不能用作Generator函数。

// function Timer() {
// this.s1 = 0;
// this.s2 = 0;
// // 箭头函数
// setInterval(() => this.s1++, 1000);
// // 普通函数
// setInterval(function () {
// this.s2++;
// }, 1000);
// }

// var timer = new Timer();

// setTimeout(() => console.log('s1: ', timer.s1), 3100);//this指向的是Timer,
// setTimeout(() => console.log('s2: ', timer.s2), 3100);//this指向全局
// // s1: 3
// // s2: 0

// var handler = {
// id: '123456',

// init: function() {
// document.addEventListener('click',
// event => this.doSomething(event.type), false);//箭头函数指向的是handler
// },

// doSomething: function(type) {
// console.log('Handling ' + type + ' for ' + this.id);
// }
// };
// 实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

// 箭头函数绑定this
//foo::bar;
// 等同于
// bar.bind(foo);

// foo::bar(...arguments);
// // 等同于
// bar.apply(foo, arguments);

// const hasOwnProperty = Object.prototype.hasOwnProperty;
// function hasOwn(obj, key) {
// return obj::hasOwnProperty(key);
// }

getPlayers()
::map(x => x.character())
::takeWhile(x => x.strength > 100)
::forEach(x => console.log(x));

posted @ 2016-10-21 16:38  overAgain  阅读(176)  评论(0编辑  收藏  举报