函数和闭包
函数默认值和箭头函数
// 函数的默认值
// 传统方式
function func(a, b) {
a = a !== undefined ? a : 2;
b = b !== undefined ? b : 5;
return (a + b);
console.log(a);
}
console.log(func());
// ES6
function func1(a = 10, b = 20) {
return a + b;
}
console.log(func1());
// --------------------------------------------------------------------
// 箭头函数
// this的指向问题
let user = {
username: "admin",
getuser: function () {
// 保存this 以便子函数可以使用this
// let thiss = this;
setTimeout(function () {
// 回调函数的作用域是全局所以this指向是window而不是当前对象
// 传统方法 把this保存在一个临时变量中,然后调用
console.log("我的名字叫 %s", this.username);
}, 1000);
},
}
// 调用对象方法
user.getuser.call(user);
// 使用箭头函数解决this的指向问题
user = {
username: "admin123456",
getuser: function () {
setTimeout(() => {
// 箭头函数的this指向是由外围最近一层非箭头函数决定的
console.log(this);
console.log("我的名字叫 %s", this.username);
}, 1000);
},
}
user.getuser();
// 箭头函数语法
// 1.无参数
// 如果函数语句就一行,那么{}可以省略
let f1 = () => console.log("箭头函数无参数");
f1();
// 2.一个参数
// 如果只有一个参数那么()可以省略,但不推荐 函数语句就一行那么 return也可以省略
let f2 = a => `我是箭头函数中的一个参数(${a})`;
console.log(f2(12));
// 3.多于一个参数 如果函数语句多于一条时,{}和return不能省略
let f3 = (...res) => res.reduce((prev, next) => prev += next, 0);
console.log(f3(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
对象字面量的扩展
// 传统对象字面量返回对象=>后面要用()包着{}
let stie = (id, name, email) => ({
id: id,
name: name,
email: email,
getname: function () {
return this.name;
},
});
let newstie = stie("1", "admin", "admin@qq.com");
console.dir(newstie);
// 如果对象属性名和参数同名,那么可以省略:后面,对象方法可以省略:function
// 简化
stie = (id, name, email) => ({
id,
name,
email,
getname() {
return this.name;
},
});
newstie = stie("2", "admin111", "admin111@qq.com");
console.dir(newstie);
// 动态生成属性名和添加前缀
let porp = "stie Name";
let obj = "user-";
let a = {
[porp]: "php.cn",
[`${obj}name`]: "admin",
[`${obj}email`]: "admin@qq.com",
getsite() {
return this["stie Name"];
},
};
console.dir(a);
闭包
// 闭包的应用场景
// 1.访问函数中的私有变量
let foo = () => {
let username = "admin";
// 现在子函数就是闭包,username现在相对于子函数就是自由变量
let get = () => username;
return get;
};
let get = foo();
console.log(get());
let manger = (n) => {
let num = n;
// 设置
let set = (val) => num = val;
// 递增
let inc = () => num++;
// 递减
let dec = () => num--;
// 打印
let print = () => console.log(num);
return { set, inc, dec, print };
};
let get1 = manger(20);
console.log(get1);
get1.print();
get1.inc();
get1.inc();
get1.print();
js的类
// 传统是用构造函数模拟类
// 原型属性:prototype,作为构造函数的时候才会用到,使该属性的指针指向新对象的__proto__上
// 原型链属性:__proto__,任何一个对象都有这个属性,指向自己的公共属性和方法,函数也是对象所以也有这个属性
function Person(name) {
// 实例对象的自由属性
this.name = name;
};
// 把公共方法放在函数的原型对象上
Person.prototype.sayName = function () {
return this.name
};
// 公共属性
Person.prototype.username = "杨果果";
let person = new Person("杨过");
console.log(person);
console.log(person.sayName());
let a = new Person("小明");
console.log(a);
console.log(a.username);
// ES6创建类
class PersonClass {
email = "admin@qq.com";
// 构造方法
constructor(name) {
this.name = name;
}
// 原型方法
sayName() {
return this.name;
}
}
person = new PersonClass("小龙女");
console.log(person);
总结
1.闭包创建四个api的案列,课件的函数表达式没有用let,var或者const声明,运行函数后就可以直接在外部调用,有点没理解其原理。
2.闭包案列函数表达式我用let声明后返回对象,当做对象方法调用不知道会不会多此一举?