javascript - Pelaksanaan kaedah panggilan dalam js
PHP中文网
PHP中文网 2017-06-12 09:30:07
0
3
796
Function.prototype.call2 = function(context) { context.fn = this; var args = []; for(var i = 1, len = arguments.length; i < len; i++) { args.push('arguments[' + i + ']'); } eval('context.fn(' + args +')'); delete context.fn; }

Ia adalah untuk mensimulasikan pelaksanaan panggilan Mengapa anda perlu menolak rentetan dan kemudian menggunakan eval seterusnya? Mengapa tidak lulus terus dalam argumen[i] dan kemudian gunakan context.fn(args)?

PHP中文网
PHP中文网

认证高级PHP讲师

membalas semua (3)
给我你的怀抱

Di sini saya percaya anda juga telah memahami arahancall的原理,这里我简要还是说明一下原理,我也是参考JavaScriptpanduan berwibawa dan kemudian melaksanakannya dengan kod.

Mula-mula, mari kita lihat sintaks dan takrifancall, daripada versi Cina bagi spesifikasi ECMAScript:

Mari kita berikan contoh mudah:

var jawil = { name: "jawil", sayHello: function (age) { console.log("hello, i am ", this.name + " " + age + " years old"); } }; var lulin = { name: "lulin", }; jawil.sayHello(24); // hello, i am jawil 24 years old

Kemudian lihat pada output selepas menggunakancall:

jawil.sayHello.call(lulin, 24);// hello, i am lulin 24 years old

Saya akan menjawab soalan anda di bawah berdasarkan buah berangan:

adalah untuk mensimulasikan pelaksanaancall的实现,请问为什么要push一个字符串,下面再用eval?直接传入arguments[i],然后下面用context.fn(args)Mengapa anda perlu menolak rentetan dan menggunakaneval seterusnya? Hantarkanarguments[i]secara langsung, kemudian gunakancontext.fn(args)mengapa tidak?

Pertama sekali, anda perlu memahami hubungan antara fungsi yang disimulasikan di atas dan pembolehubah dalam chestnut:

context => lulin context.fn => jawil.sayHello

Perhatikan langkah ini, kami hanya meletakkanjawil.sayHello的引用地址给了lulin.sayHello

Ternyatajawil.sayHello.call(context,arg1,arg2,arg3,arg4)

Potong cara andacontext得到args=[arg1,arg2,arg3,arg4]

Kemudian laksanakanlulin.sayHello([arg1,arg2,arg3,arg4])Haha, ia sangat mengelirukan, bukan? Di sinilah letak masalahnya.

Jadi bagaimana untuk menyelesaikan masalah ini? Ideanya adalah seperti di atas, masukkan semua parameter ke dalam rentetan, dan kemudian gunakanevaluntuk melaksanakan.

Kesan yang kami mahukan ialahlulin.sayHello(arg1,arg2,arg3,arg4), keranalulin.sayHelloperlu menyusun semula parameter, anda tidak bolehlulin.sayHello(arg1,arg2,arg3,arg4)这样的,因为lulin.sayHello要重组参数,你不能拿到一个参数执行一次函数吧,或者把参数存到一起一次执行吧,唯一的想到的做法就是把所有参数拼成字符串,然后用evaldapatkan satu Jalankan fungsi sekali dengan parameter

, atau

simpan parameter bersama-sama dan laksanakannya sekalilulin.sayHello([arg1,arg2,arg3,arg4]),也不是lulin.sayHello(arg1),lulin.sayHello(arg2)Satu-satunya cara yang terlintas di fikiran ialah meletakkan semua parameter ke dalam rentetan, dan kemudian gunakan

untuk melaksanakan,

.

Serupa dengan ini: "lulin.sayHello(arg1,arg2,arg3,arg4)" Ini adalah cara yang kita mahu, bukan

, mahupunlulin.sayHello(arg1),lulin.sayHello (arg2)...eval
Apakah itu eval? Biar saya terangkan secara ringkas di sini.

Mari kita lihat secara ringkas

fungsi

definisi dan penggunaan
Fungsi


eval() boleh mengira rentetan dan melaksanakan kod JavaScript di dalamnya.eval(string)

Tatabahasa:

rentetan diperlukan. Rentetan untuk menilai yang mengandungi ungkapan JavaScript untuk dinilai atau pernyataan untuk dilaksanakan. Kaedah ini hanya menerima rentetan mentah sebagai parameter, jika parameter rentetan bukan rentetan mentah, maka kaedah itu akan kembali tidak berubah. Oleh itu, jangan berikan objek String sebagai argumen kepada fungsi eval().

Secara ringkasnya, ia menggunakan enjin penghuraian JavaScript untuk menghuraikan kandungan sekumpulan rentetan ini, anda boleh memahaminya dengan cara ini, anda meletakkan tegeval看成是

Baiklah, mari kita lihat semula kod di atas Sebenarnya, masih terdapat masalah. Di bawah ialah kod penyahpepijatan lengkap:

Function.prototype.call2 = function(context) { context.fn = this; var args = []; for (var i = 1, len = arguments.length; i < len; i++) { args.push('arguments[' + i + ']'); } console.log(args) var star = 'context.fn(' + args + ')' console.log(star) eval('context.fn(' + args + ')'); delete context.fn; } var jawil = { name: "jawil", sayHello: function(age) { console.log("hello, i am ", this.name + " " + age + " years old"); } }; var lulin = { name: "lulin", }; jawil.sayHello.call2(lulin, 24, 25);

Lihat output args:

["hujah[1]", "hujah[2]"]

Kemudian lihat pada output 'context.fn(' + args + ')':

"context.fn(arguments[1],arguments[2])"Bukankah ia agak mengelirukan

Malah, penukaran tersirat terlibat di sini:

'jawil'+[1,2]+[3,4]+3sama dengan apa?'jawil'+[1,2]+[3,4]+3等于多少?
等于"jawil1,23,43"
其实这个相当于'jawil'+[1,2].toString()+[3,4].toString()+3Sama dengan"jawil1,23,43"

Malah, ini bersamaan dengan 'jawil'+[1,2].toString()+[3,4].toString( )+3

Ruang adalah terhad, untuk penukaran yang lebih tersirat, sila rujuk artikel saya: Daripada ++[[]][+[]]+[+[]]==10? Penjelasan mendalam tentang penukaran tersirat dalam taip lemah JS

Bercakap tentang ini, saya telah mengatakan semua perkara yang anda boleh memahaminya sendiri. Penulis asal mungkin merujuk kepada orang lain ketika menulis ini ia dalam satu pukulan Nampaknya ia adalah perenggan yang sangat pendek. Kod ini sebenarnya mengandungi banyak mata pengetahuan.
    曾经蜡笔没有小新

    args ialah tatasusunan,context.fn(args)hanya mempunyai satu parameter Dalam keadaan biasa, anda boleh menggunakan apply untuk menukar tatasusunan kepada parameter, tetapi di sini untuk mensimulasikan panggilan, menggunakan apply tidak bermakna. Jadi ia menggunakan toString() tatasusunan untuk memindahkan parameter selain daripada konteks ke context.fn.

      淡淡烟草味

      Kerana hujah[0] ialah konteks
      Tidakkah anda nampak bahawa pembolehubah gelung bermula dari 1?

        Muat turun terkini
        Lagi>
        kesan web
        Kod sumber laman web
        Bahan laman web
        Templat hujung hadapan
        Tentang kita Penafian Sitemap
        Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!