/**
* 函数的扩展
*/
'use strict';
/*
* 函数参数默认值
*/
function Point(x=0, y=0){
let x;
this.x = x;
this.y = y;
};
let p = new Point(false, false);
// 设置了函数参数的默认值 是个空对象
// 设置了解构赋值的默认值
function m1( {x=0, y=0} = {} ){
console.log(x, y);
};
// 设置了函数参数的默认值是个具体对象
// 没设置解构赋值的默认值
function m2( {x, y} = {x:0, y:0} ){
console.log(x, y);
};
m1();
m2();
m1({x:3, y:4});
m2({x:3, y:4});
m1({});
m2({});
// 变量z的值先取内部作用域 如果没有值再取外部作用域
let z = 1;
function x(y=z){
console.log(y);
}
x();
/**
* rest参数
*/
// ...变量名 用于获取函数的多余参数 是个数组
function add(...values){
let sum = 0;
for(var val of values){
sum += val;
}
console.log(sum, values);
};
add(2, 5, 3);
function add (...values, a) {
// rest 参数之后不能再有其他参数 否则报错
}
add(2, 5, 3)
// 扩展运算符 ...
// 扩展运算符(spread)是三个点(...) 它好比 rest 参数的逆运算 将一个数组转为用逗号分隔的参数序列
// 参数里的 ...items 是 [1, 2, 3]
// 函数体内的 ...items 是 1, 2, 3 传进来的原始参数值
function push(array, ...items){
array.push(...items);
console.log(array);
};
push([4], 1,2,3);
function add(x, y){
console.log(x, y);
};
let numbers = [4, 38];
// ...numbers 把数组转化成逗号分隔的参数序列
add(...numbers);
// 合并数组
let more = [3, 4];
[1, 2, ...more]
let arr1 = ['a', 'b'];
let arr2 = ['c'];
let arr3 = ['d', 'e'];
[...arr1, ...arr2, ...arr3];
// 与解构赋值结合
// 如果将扩展运算符用于数组赋值 只能放在参数的最后一位 否则会报错
let list = [1, 2, 3];
// a = 1; ...rest接受剩余的其他值 并转化成数组
let [a, ...rest] = list;
// a=1, rest=[2, 3]
console.log(a, rest);
// 扩展运算符将字符串转换成逗号分隔的参数序列
console.log(...'hello');
/**
* 箭头函数
* 箭头函数 只要写了 {} 需要在里面写return 才可以返回值
*/
// 等价于下面的写法
var f = v => v;
var f = function (v){return v};
// 多个参数写法
let f = (num1, num2) => num1 + num2;
f(1, 2);
// 箭头函数多余一条语句 如果要返回内容 需要用return
let fn = v => {
let a = 1
v
}
// undefined
log( fn(1) )
// 如果要返回对象 并且只有一条语句 外面必须加上大括号
let fn = v => ({a: 1})
// {a: 1}
log( fn() )
// 箭头函数与变量解构结合使用
const full = ({first, last}) => first + ' ' + last;
full({first:1, last:2});
// 箭头函数和map用法
let num = [1, 2, 3].map( (x, y, z) => x*x );
// 箭头函数和rest用法
const numbers = (...nums) => nums;
numbers(1, 2, 3);
// 函数体内的this对象 就是定义函数时所在的对象 而不是使用函数时所在的对象
function foo(){
// 这里的this指{id:1} 是在执行apply以后才定义了setTimeout的函数体
setTimeout( ()=>console.log('id : ', this.id), 1000 );
};
foo.apply({id:1});
// 输出3, 0
// this 是当前实例
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭头函数
setInterval(() => this.s1++, 1000);
// 普通函数
setInterval(function () {
this.s2++;
}, 1000);
};
let timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// 箭头函数 固定化this指向
let handler = {
id : '123',
init : function (){
// this通过箭头函数固定指向了handler 点击事件时没有改变this
document.addEventListener('click', event => this.doSo(event.type), false);
},
doSo : function (type){
console.log(type, this.id);
}
};
handler.init();
// 箭头函数没有自己的this 所以bind无效 这里输出2
(function (){
( () => this.x ).bind( {x:1} )();
}).call({x:2});