1. Revisión de demo01
①operador in: determinar si un objeto tiene una propiedad (o decir: determinar si existe una propiedad en el objeto)
let obj = {
name:"二哈",
sex:"男",
age:12
}
if("name" in obj){
console.log("obj中有name属性");
}
②Proxy: proxy, que puede representar un objeto.
1. Cuando se usa: cuando es necesario manipular el objeto de origen, ahora se manipula el objeto proxy. El objeto proxy manipula el objeto fuente.
2. Para qué se utiliza: puede establecer una barrera entre el objeto de origen y la operación (por ejemplo, puede juzgar la legalidad del valor del atributo)
// 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属性");
}
2. Cierre
1. Comprensión superficial: definiciones de funciones anidadas. Las funciones internas son funciones locales.
2. Comprensión profunda: una función y sus referencias de estado circundante (datos) están unidas, y tal combinación es un cierre.
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();
}
3. Proceso de ejecución de código con cierre
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//产生一个闭包
4. Escenario de cierre: un objeto con un solo método
function person(str){
var name = str;
return function(){
console.log(name+"在吃,天在看……");
}
}
let eat = person("宋和叶");
eat();
5. Escenario de cierre: si algunos datos solo quieren ser utilizados por ciertas funciones (haga que los datos sean privados, también puede hacer que el método sea privado)
// 需求:某些数据只希望某些函数使用
// 如下示例: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());
6. Comparación con cierres y clases
//闭包
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);
}
}
7. Usa cierres en bucles
/*
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);
8. Alcance y cadena de alcance
// 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();
}
9. Curry de funciones
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);