一、demo01回顾
①in 运算符:判断一个对象是否有某个属性(或者说:判断一个属性是否在对象中有)
let obj = {
name:"二哈",
sex:"男",
age:12
}
if("name" in obj){
console.log("obj中有name属性");
}
②Proxy:代理,可以代理一个对象。
1、使用的时候:当需要操作源对象时,现在操作代理对象。代理对象会操作源对象。
2、干什么用:能够在源对象和操作之间设立一个屏障(如:可以判断属性值的合法性)
// 1)、修改源对象的age属性
let p1 = new Proxy(obj,{
set:function(target,key,val){
if(val<0 || val>150){
return;
}
target[key] = val;
},
has:function(target,key){
console.log('has');
return key in target;
}
});
p1.age = 250;
// 2)、 当判断对象中是否有某个属性(用in操作符)
if( "age" in p1){
console.log("obj有age属性");
}
二.闭包
1、粗浅理解:嵌套的函数定义。里面的函数是局部函数。
2、深度理解:一个函数和其周围状态(数据)的引用,绑定在一起,这样的组合才是闭包。
function fn01() {
var num = 10;
console.log("num", num);
// fn02是局部函数
function fn02() {
console.log("fn02");
}
// fn02();
return fn02;//如果希望在外面调用fn02。可以返回出去。
}
let f = fn01();
document.getElementById("btn01").onclick = function () {
f();
}
三.带有闭包的代码执行过程
function fn01() {
var num = 10;
function fn02() {
num++;
console.log("num", num);
}
return fn02;
}
let f = fn01();//产生一个闭包
f();//num:11
f();//num:12
f();//num:13
let f2 = fn01();//产生一个闭包
f2();//11
f();//14;
f2();//12
fn01()(); //11//产生一个闭包
fn01()(); //11//产生一个闭包
四.闭包的场景:只有一个方法的对象
function person(str){
var name = str;
return function(){
console.log(name+"在吃,天在看……");
}
}
let eat = person("宋和叶");
eat();
五.闭包的场景:如果某些数据只希望某些函数使用(让数据私有,也可以让方法私有)
// 需求:某些数据只希望某些函数使用
// 如下示例:count只希望fn01和fn02可以使用。
function person() {
var count = 10;
function fn01() {
count += 2;
console.log("fn01:count", count);
}
function fn02() {
count++;
console.log("fn02:count", count);
}
return [fn01];
}
function fn03() {
}
console.log(person());
六.用闭包和类进行对比
//闭包
function person(){
var count = 10;//count:可以在fn01和fn02函数共享
function fn01(){
count+=2;
console.log("fn01:count",count);
}
function fn02(){
count++;
console.log("fn02:count",count);
}
return [fn01];
}
function fn03(){
}
//类
class dog{
constructor(){
this.count = 2;//count:可以在fn01和fn02函数共享
}
fn01(){
this.count+=2;
console.log("fn01:count",this.count);
}
fn02(){
this.count+=1;
console.log("fn02:count",this.count);
}
}
七.循环里使用闭包
/*
function fn1(){
let arr = [];
for(var i=0;i<5;i++){
//循环体中,完成的事情:给数组的元素赋值,不会调用函数
arr[i] = function(){
return i;
}
}
console.log(i); //5,循环结束后,i的值是5;
return arr;
}
var arr2 = fn1();
console.log(arr2[0]());//
console.log(arr2[1]());
*/
function fn1(){
let arr = [];
for(var i=0;i<5;i++){
//循环体中,完成的事情:给数组的元素赋值,不会调用函数
arr[i] = (function(){
return i;
})();
}
console.log(i); //5,循环结束后,i的值是5;
return arr;
}
var arr2 = fn1();
console.log("arr2",arr2);
八.作用域和作用域链
// 1、ES5及其之前
var count = 100;
function fn01() {
var n = 20;
count++;
console.log("fn01:count", count);
console.log("fn01:n", n);
}
function fn02() {
count--;
console.log("fn02:count", count);
}
function add(){
fn01();
}
function sub(){
fn02();
}
// 2、ES6+;
let count = 100;
function fn01() {
let n = 20;
count++;
if(true){
let m = 10;
console.log("m",m);
console.log("n",n);
console.log("count",count);
}
{
let y =30;
console.log("y",y);
}
console.log("fn01:count", count);
console.log("fn01:n", n);
}
function fn02() {
count--;
console.log("fn02:count", count);
}
function add(){
fn01();
}
function sub(){
fn02();
}
九.函数的柯里化
function sum(a,b,c){
return a+b+c;
}
sum(3,4,5)
// 一、柯里化函数的意思:
function sum(m){
return function(n){
return function(k){
return m+n+k;
}
}
}
let s = sum(3)(4)(5);
console.log("s",s);
// 二、柯里化工具:把一个函数进行柯里化
function sum(a,b,c,d){
return a+b+c+d;
}
function curry(cb){
//这个数组是保存原函数的参数的。
let arrs = [];
//这个函数(fn),用来收集原函数的参数,如果没有收集够,就返回函数(fn)本身;如果收集够
//了,那就调用原函数(cb)
function fn(...args){
arrs = [...arrs,...args];//[1,2,3,4]
if(arrs.length<cb.length){//判断实参个数是否和原函数的形参个数的关系
return fn;
}else{
return cb(...arrs);
}
}
return fn;
}
let sfn = curry(sum);
let s = sfn(1)(2)(3)(4);
let s = sfn(1,2)(3)(4);
let s = sfn(1,2,3)(4);
let s = sfn(1,2)(3,4);
let s = sfn(1,2,3,4);
// 三、柯里化工具函数(进一步)
function sum(a,b,c,d){
return a+b+c+d;
}
// 把sum(a,b,c,d)转成 sum(a)(b)(c)(d);
function curry(cb,arr=[]){
return function(...args){
let arrs = [...arr,...args];//1
if(arrs.length<cb.length){//判断实参个数是否和原函数的形参个数的关系
return curry.call(this,cb,arrs)//调用闭包时,传入arrs,把前面调用的状态进行保持。
}else{
return cb(...arrs);
}
}
}
let sfn = curry(sum);
let s = sfn(1)(2)(3)(4);