Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

es6代理模式proxy的两个应用 #30

Open
zp1112 opened this issue Aug 7, 2020 · 0 comments
Open

es6代理模式proxy的两个应用 #30

zp1112 opened this issue Aug 7, 2020 · 0 comments

Comments

@zp1112
Copy link
Owner

zp1112 commented Aug 7, 2020

Proxy

Proxy意思为“代理”,即在访问对象之前建立一道“拦截”,任何访问该对象的操作之前都会通过这道“拦截”,即执行Proxy里面定义的方法。
基本用法

let pro = new Proxy(target,handler);
  1. new Proxy()表示生成一个Proxy实例
  2. target参数表示所要拦截的目标对象
  3. handler参数也是一个对象,用来定制拦截行为。

这里不讲proxy的原理,只讲proxy在我们实际项目中可以利用到的地方。

图片懒加载

图片的加载需要一定的时间,我们常常希望在图片加载成功之前显示一个占位图,那么可以使用proxy在html渲染图片的时候通过替换src来实现,因为html渲染图片img标签的时候实际是在执行一个get操作,因此可以使用proxy来实现

function proxyImg(img, loadingImg, realImg) {
  const vImg = new Image();
  let hasLoad  = false;
  vImg.src = realImg;
  vImg.onload = function() {
    Reflect.set(img, 'src', realImg);
    hasLoad = true;
  }
  return new Proxy(img, {
    get(obj, prop) {
      if(prop === 'src' && !hasLoad) {
       return loadingImg;
      } else {
       return obj[prop];
      }
    }
  })
}
// 使用
const img = new Image();
document.body.appendChild(proxyImg(img, './loading.gif', './xx.png'))

obj属性赋值

项目中常常要遇到这样一个场景

const obj = {};
if(!obj.style) { obj.style = {} }
else {
  obj.style.left = '200px';
  obj.style.top = '100px';
}

每次都要多一个是否存在属性,不存在则初始化一个空对象,否则会报错can not assign to an undefined的错误,那么我们使用proxy来创建一个空对象,并拦截get操作,即可实现

const EmptyObject = function () {
  return new Proxy({}, {
    get: (target, property) => {
      if (!(property in target)) {
        target[property] = {};// 将判断为空的放在拦截器里面
      }
      return target[property];
    }
  })
};
// 使用
const obj = EmptyObject();
obj.test.test1 = 0;
console.log(888, obj)

总结

Proxy的应用非常多,在实际项目中要经常动脑,思考有没有可以借助Proxy实现的一些场景,来方便我们的编码。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant