关于new从一个BUG说起
前言
今天在一个前端群组里,看到有人发出一个问题:
var o = new Object();function foo(obj){ var obj = o; obj.name = '123'; obj = new Object(); obj.name = '456'; } foo(o); console.log(o.name)
如上代码所示,在不改变任何条件和数据的情况下,有没有可能输出“456”?
没多久,群组中人就开始下结论,正常情况下是不能的。
原因吗,稍微知道引用类型的使用方式的人都知道的,new Object(),改变了obj的指向,永远没法获得456。
问题来了
正常情况下不可能输出456,那在什么样的错误情况下能够输出456呢?毕竟程序员就是擅长写BUG的吗,应该能够搞得非正常情况的吧。
然后,手残的自己突然想到前两天刚学习的Proxy。我们现在是赋值时出的问题,那么能不能从元数据上解决问题呢?尝试一下:
//demo_01var o = new Object(); o = new Proxy(o,{ set(target, key, value,receiver){ if(Object.is('name',key)) return Reflect.set(target, key, `456`,receiver); return Reflect.set(target, key, value , receiver); } })function foo(obj){ var obj = o; obj.name = '123'; obj = new Object(); obj.name = '456'; } foo(o); console.log(o.name)
完美,成功地输出了456。
什么?你不知道Proxy是什么?点击这里 –> ES6 拦截器,Proxy
那么,现在就是嘚瑟的时间了,准备将结果发送到群组炫耀下。先翻看下聊天记录,呦呵,已经有人给出了一个答案,比我还快。好吧,先看看人家的答案:
//demo_02var o = new Object();Object.defineProperty(o,'name',{ set(val){ this.value = '456'; }, get(){ return this.value; } })function foo(obj){ var obj = o; obj.name = '123'; obj = new Object(); obj.name = '456'; } foo(o); console.log(o.name)
厉害的小伙子,跟我想到了一起去了,都是在getter和setter上做文章,都是在元级别上处理数据。
这位同学同时贴出一篇文章,说是从这里获取的灵感,狠戳这里,一起欣赏下吧,写得的确很不错 –> 无懈可击的钩子
接下来,也贴下我的答案吧,就当时凑个热闹吧。等等,有人表示不服了,说他是在投机取巧。demo_02代码完全等价与demo_03代码:
//demo_03var o = new Object();function foo(obj){ var obj = o; obj.name = '123'; obj = new Object(); obj.name = '456'; } foo(o); o.name = '456'; console.log(o.name);
当demo_02的方法中最后一行代码”obj.name = ‘456’;”进行修改时,demo_02的代码中的”this.value = ‘456’;”也得随之修改。
说的好有道理,我们的确是在投机取巧,我写得demo_01也是同样的问题,还好没点回车键,不然就没脸了。
那么有没得什么办法可以解决这里问题,实现真正的输出456
new操作符做了什么工作呢?
话说我们现在的问题是什么呢?问题就是处在了new Object()上,它修改了obj的this指向,那么我们有没有什么办法规避呢?
什么?你问我为什么this指向改变了,我只能说,你真的得好好学习JS了,看看这篇文章吧,作者的笔风好有趣,从一个士兵说起new都做了什么
我记得在Proxy的handler中有个construct方法,如果我能在Object构造器中修改它的this。想法很好,但是失败了,没能实现。如果,有哪位能在这个思路上走下去,求告知答案 >_<
查看聊天记录,那位同学又给出了一种解决方法:
var o = new Object();var _Object = Object;Object = function(){ return o; }function foo(obj){ var obj = o; obj.name = '123'; obj = new Object(); obj.name = '456'; } foo(o); console.log(o.name)Object = _Object;
这次这位同学先重写了Object对象,让它返回o这个对象,这就避免了this指向的变动,有才啊,佩服。默默收藏<_<
努力吧,总有人能教会你点什么
Atas ialah kandungan terperinci 关于new从一个BUG说起 . Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Soalan dan penyelesaian yang sering ditanya untuk percetakan tiket kertas terma depan dalam pembangunan front-end, percetakan tiket adalah keperluan umum. Walau bagaimanapun, banyak pemaju sedang melaksanakan ...

Tidak ada gaji mutlak untuk pemaju Python dan JavaScript, bergantung kepada kemahiran dan keperluan industri. 1. Python boleh dibayar lebih banyak dalam sains data dan pembelajaran mesin. 2. JavaScript mempunyai permintaan yang besar dalam perkembangan depan dan stack penuh, dan gajinya juga cukup besar. 3. Faktor mempengaruhi termasuk pengalaman, lokasi geografi, saiz syarikat dan kemahiran khusus.

JavaScript adalah asas kepada pembangunan web moden, dan fungsi utamanya termasuk pengaturcaraan yang didorong oleh peristiwa, penjanaan kandungan dinamik dan pengaturcaraan tak segerak. 1) Pengaturcaraan yang didorong oleh peristiwa membolehkan laman web berubah secara dinamik mengikut operasi pengguna. 2) Penjanaan kandungan dinamik membolehkan kandungan halaman diselaraskan mengikut syarat. 3) Pengaturcaraan Asynchronous memastikan bahawa antara muka pengguna tidak disekat. JavaScript digunakan secara meluas dalam interaksi web, aplikasi satu halaman dan pembangunan sisi pelayan, sangat meningkatkan fleksibiliti pengalaman pengguna dan pembangunan silang platform.

Bagaimana cara menggabungkan elemen array dengan ID yang sama ke dalam satu objek dalam JavaScript? Semasa memproses data, kita sering menghadapi keperluan untuk mempunyai id yang sama ...

Perbincangan mengenai realisasi kesan animasi tatal dan elemen Parallax dalam artikel ini akan meneroka bagaimana untuk mencapai yang serupa dengan laman web rasmi Shiseido (https://www.shiseido.co.jp/sb/wonderland/) ... ...

Perbincangan mendalam mengenai punca-punca utama perbezaan dalam output konsol.log. Artikel ini akan menganalisis perbezaan hasil output fungsi Console.log dalam sekeping kod dan menerangkan sebab -sebab di belakangnya. � ...

Pembelajaran JavaScript tidak sukar, tetapi ia mencabar. 1) Memahami konsep asas seperti pembolehubah, jenis data, fungsi, dan sebagainya. 2) Pengaturcaraan asynchronous tuan dan melaksanakannya melalui gelung acara. 3) Gunakan operasi DOM dan berjanji untuk mengendalikan permintaan tak segerak. 4) Elakkan kesilapan biasa dan gunakan teknik debugging. 5) Mengoptimumkan prestasi dan mengikuti amalan terbaik.

Terokai pelaksanaan fungsi seretan panel dan drop panel seperti VSCode di bahagian depan. Dalam pembangunan front-end, bagaimana untuk melaksanakan vscode seperti ...
