Rumah > hujung hadapan web > View.js > Tidak mengapa jika anda tidak tahu Vue, tetapi anda mesti tahu cara menggunakan Proksi!

Tidak mengapa jika anda tidak tahu Vue, tetapi anda mesti tahu cara menggunakan Proksi!

藏色散人
Lepaskan: 2023-04-14 17:23:30
ke hadapan
1718 orang telah melayarinya

Saya mempunyai idea untuk menulis artikel ini beberapa bulan yang lalu, tetapi saya fikir titik pengetahuan ini VueJs lebih kerap digunakan saya sendiri React Jika saya memilih Bila yang lain ia datang kepada rangka kerja, saya mungkin lebih suka angular, tetapi saya telah belajar NestJs baru-baru ini dan mendapati bahawa Reflect digunakan secara meluas di lapisan bawah, seperti berikut:

Tidak mengapa jika anda tidak tahu Vue, tetapi anda mesti tahu cara menggunakan Proksi!

Baiklah, saya di sini Itulah sebabnya saya menulis artikel ini hari ini. Artikel ini akan dijelaskan dalam urutan Object -> > ObjekProxyReflectDalam

, kita boleh mentakrifkan objek dan mengendalikannya (tambah atau cari), seperti yang ditunjukkan dalam kod berikut:

Jika kita mahu Apabila memantau objek, kami berharap dapat memantau proses menetapkan atau mendapatkan sifat dalam objek ini. Kami boleh melakukan ini melalui sifat yang disimpan dalam ES5deskriptor hartanah

.
const moment = {
  age: 18,
  address: "西安",
};

moment["hobby"] = "basketball";
moment.hight = 1.59;

console.log(moment.age); // 18
Salin selepas log masuk

Deskriptor atributDalam

, semua atribut mempunyai deskriptor atribut Penggunaan khusus adalah seperti yang ditunjukkan dalam rajah di bawah:

ES5 <🎜. >Seperti yang ditunjukkan dalam gambar di atas, deskriptor atribut yang sepadan dengan atribut objek biasa ini bukan sekadar

18

, ia juga mengandungi tiga ciri lain, iaitu: Tidak mengapa jika anda tidak tahu Vue, tetapi anda mesti tahu cara menggunakan Proksi!

;

    ;
  • writable
  • ;
  • enumerable
  • Apabila mencipta jenis rumah biasa, deskriptor atribut akan digunakan Nilai lalai, kita boleh gunakan
  • untuk menambah atribut baharu atau mengubah suai atribut sedia ada (apabila nilai atribut configurable ialah
  • ) dan tetapkan ciri, seperti ditunjukkan dalam kod berikut:

Object.defineProperty(...)Ini kaedah menerima tiga parameter, iaitu: Configurabletrue

Objek untuk mentakrifkan atribut; >Deskriptor atribut untuk ditakrifkan atau diubah suai;
const moment = {
  age: 18,
  address: "西安",
};

Object.defineProperty(moment, "address", {
  value: "肇庆",
  writable: true,
  configurable: true,
  enumerable: true,
});

console.log(moment.address); // 肇庆
Salin selepas log masuk

Getter dan Setter
  • Saya telah bercakap tentang banyak perkara asas sebelum ini, tetapi saya tidak menjelaskan cara menerimanya atribut, di sini, deskriptor atribut
  • menyediakan dua atribut, ia adalah
  • dan Symbol Penggunaan dua atribut adalah seperti berikut:
  • Apabila kita menetapkan nilai kepada <. 🎜>, kaedah pada atribut
akan dipanggil dan

akhirnya akan menjadi output.

Apabila kita mendapat nilai Object.defineProperty, kaedah pada atribut set akan dipanggil, dan akhirnya get akan menjadi output.

const moment = {
  age: 18,
  address: "西安",
};

Object.keys(moment).forEach((key) => {
  let value = moment[key];
  Object.defineProperty(moment, key, {
    get: function () {
      console.log(`监听到了对象的 ${key} 属性被访问了`);
      return value;
    },

    set: function (params) {
      console.log(`监听到了对象的 ${key} 属性被修改了`);
      value = params;
    },
  });
});

moment.age = 22;
const foo = moment.address;
Salin selepas log masuk
Walaupun kedua-dua kaedah ini boleh dilakukan, jika kita ingin memantau operasi yang lebih kaya, ia tidak boleh, seperti menambah atribut dan atribut pudar, menggunakan

tidak boleh 🎜>moment.agesetKeputusan akhir adalah seperti yang ditunjukkan dalam gambar di atas. 监听到了对象的 age 属性被修改了

Kemudian kemunculan

menyelesaikan titik kesakitan ini dengan baik. moment.addressgetProksi监听到了对象的 address 属性被访问了

Dalam

, kelas Object.defineProperty(...) baharu ditambah seperti yang anda lihat dari namanya, kelas ini digunakan untuk membantu kami membuat proksi objek khas yang dibuat oleh anda. Ia membungkus objek biasa lain atau berdiri di hadapan objek biasa ini. Contohnya, jika anda ingin mengubah suai objek, ia mempunyai carta alir berikut:

Tidak mengapa jika anda tidak tahu Vue, tetapi anda mesti tahu cara menggunakan Proksi!<🎜. >

Ia seperti tahap yang memintas operasi anda.

Penggunaan asas kelas ini adalah seperti berikut:

Proxy

Anda akan mendapati ia mengembalikan objek yang sama, tetapi alamat memori berbeza, jadi nilai yang dikembalikan oleh perbandingan kesamaan yang ketat ialah

.

Peoxy's 13 capturersES6Proxy

Terdapat 13 penangkap kesemuanya, tetapi terdapat hanya beberapa yang biasa digunakan Berikut ialah penjelasan terperinci mengenainya, anda boleh menyemak

Tapak web Rasmi MDN Tidak mengapa jika anda tidak tahu Vue, tetapi anda mesti tahu cara menggunakan Proksi!

Tanpa berlengah lagi, mari terus ke kod:

Dalam kod di atas, kedua-dua
const moment = {
  age: 18,
  address: "西安",
};

const proxy = new Proxy(moment, {});

console.log(proxy); // { age: 18, address: &#39;西安&#39; }
Salin selepas log masuk
dan

kembalikan false, iaitu

sepadan dengan objek yang akan diubah suai, dan

ialah objek

atau mewarisi

. Peoxy

操作 Proxy 的同时会修改 moment 对象。

可取消代理

普通对象总是陷入到目标对象,并且在创建之后不能改变,只要还保持着对这个代理的引用,代理的机制就将维持下去。

但是可能会存在这样的情况,比如你想要创建一个在你想要停止它作为代理时便可被停用的代理,解决的方案是创建可取消代理,具体代码如下所示:

const moment = {
  age: 18,
  address: "西安",
};

const { proxy, revoke } = Proxy.revocable(moment, {
  get: function (target, key, receiver) {
    console.log("get 捕获器");
  },
});

proxy.address;
revoke();
proxy.address;
Salin selepas log masuk

最终的输出如下图所示:

Tidak mengapa jika anda tidak tahu Vue, tetapi anda mesti tahu cara menggunakan Proksi!

一旦可取消代理被取消,任何对他的访问都会抛出 TypeError 错误。

Proxy的问题与不足

尽管现在 Proxy 已经做得很好了,但是在某些情况下,代理也不能与现在的 ECMAScript 机制很好地协同。

Proxy中的this

Peoxy 潜在的一个问题来源是 this 值,我们知道方法中的 this 通常执行调用这个方法的对象,具体代码如下所示:

const target = {
  moment() {
    return this === proxy;
  },
};

const proxy = new Proxy(target, {});

console.log(target.moment()); // false
console.log(proxy.moment()); // true
Salin selepas log masuk

按照正常的理解这是没有问题的调用 Proxy 上的任何方法,而这个方法进而又会调用另一个方法,实际上都会调用 Proxy 内部的方法,这是符合预期的行为,但是,如果目标对象依赖于对象表示,那就可能碰到意料之外的问题。

举个例子:

const wm = new WeakMap();

class User {
  constructor(userId) {
    wm.set(this, userId);
  }

  set id(userId) {
    wm.set(this, userId);
  }
  get id() {
    return wm.get(this);
  }
}
Salin selepas log masuk

由于这个实现依赖 User 实例的对象标识,在这个实例被代理的情况下就会出现问题:

const user = new User(1);
console.log(user.id); // 1

const proxy = new Proxy(user, {});
console.log(proxy.id); // undefined
Salin selepas log masuk

这是因为 User 实例一开始使用目标对象作为 WeakMap 的键,代理对象却尝试从自身取得这个实例,要解决这个问题,就需要重新设置代理,把代理 User 实例改为代理 User 类本身,之后再创建代理的实例就会创建代理实例作为 WeakMap 的键了:

const UserProcess = new Proxy(User, {});
const proxy = new UserProcess(1);
console.log(proxy.id); // 1
Salin selepas log masuk

Proxy与内部槽位

代理与内置引用类型的实例通常可以很好地协同,但有些 ECMAScript 内置类型可能会依赖代理无法控制的机制,结果导致在代理上调用某些方法会出错,具体代码如下所示:

const target = new Date();

const proxy = new Proxy(target, {});

console.log(proxy instanceof Date); // true
proxy.getDate(); // TypeError: this is not a Date object.
Salin selepas log masuk

在上面的代码中,根据 ECMAScript 规范,Date 类型方法的执行依赖 this 值上的内部曹伟 [[NumberDate]],代理对象上不存在这个内部槽位,而且这个内部槽位的值也不能通过普通的 get()set() 操作访问到,于是代理拦截后本应该转发给目标对象的方法会抛出 TypeRrror 的错误。

这篇文章到此结束,下一篇将会详细讲解 Reflect,敬请期待。

Atas ialah kandungan terperinci Tidak mengapa jika anda tidak tahu Vue, tetapi anda mesti tahu cara menggunakan Proksi!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
vue
sumber:juejin.im
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan