Rumah >hujung hadapan web >tutorial js >Hidupkan mod lawatan penggunaan untuk memohon, memanggil dan mengikat kemahiran Javascript_javascript

Hidupkan mod lawatan penggunaan untuk memohon, memanggil dan mengikat kemahiran Javascript_javascript

WBOY
WBOYasal
2016-05-16 15:34:461098semak imbas

Saya berharap melalui artikel ini, saya dapat meningkatkan pemahaman saya dengan jelas tentang memohon, memanggil dan mengikat, dan menyenaraikan beberapa kegunaan hebatnya untuk memperdalam ingatan saya.

mohon, hubungi

Dalam JavaScript, panggil dan gunakan kedua-duanya wujud untuk menukar konteks apabila fungsi sedang berjalan, dengan kata lain, mereka perlu menukar penunjuk ini di dalam badan fungsi.

Ciri utama JavaScript ialah fungsi mempunyai konsep "konteks definisi" dan "konteks masa jalan" serta "konteks boleh diubah".

Biar saya berikan anda contoh kod dahulu:

function fruits() {}
fruits.prototype = {
  color: "red",
  say: function() {
    console.log("My color is " + this.color);
  }
}
var apple = new fruits;
apple.say();  //My color is red

Tetapi jika kita mempunyai objek pisang= {color : "yellow"} dan kita tidak mahu mentakrifkan semula kaedah sebutnya, maka kita boleh menggunakan kaedah apple's say melalui panggilan atau gunakan:

banana = {
  color: "yellow"
}
apple.say.call(banana);   //My color is yellow
apple.say.apply(banana);  //My color is yellow

Jadi, dapat dilihat bahawa panggilan dan aplikasi kelihatan mengubah ini secara dinamik apabila objek tidak mempunyai kaedah tertentu (pisang dalam chestnut ini tidak mempunyai kaedah sebut), tetapi yang lain melakukannya (epal dalam chestnut ini mempunyai. kaedah katakan), kita boleh menggunakan panggilan atau memohon untuk beroperasi menggunakan kaedah objek lain.

Perbezaan antara memohon dan menelefon

Untuk kedua-dua permohonan dan panggilan, fungsinya adalah sama, tetapi cara menerima parameter adalah berbeza. Sebagai contoh, terdapat fungsi yang ditakrifkan seperti berikut:

var func = function(arg1, arg2) { 
};

boleh dipanggil seperti berikut:

func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])

Di mana ini adalah konteks yang anda ingin tentukan, ia boleh menjadi mana-mana objek JavaScript (semuanya dalam JavaScript adalah objek), panggilan perlu menghantar parameter mengikut tertib dan menerapkan meletakkan parameter dalam tatasusunan.

Dalam JavaScript, bilangan parameter fungsi tidak tetap, jadi jika anda ingin menggunakan syarat, gunakan panggilan apabila nombor parameter anda diketahui dengan jelas.

Apabila anda tidak pasti, gunakan apply, kemudian tolak parameter ke dalam tatasusunan dan hantarkannya. Apabila bilangan parameter tidak pasti, semua parameter boleh dilalui di dalam fungsi melalui tatasusunan argumen.

Untuk menyatukan dan mendalami ingatan, berikut adalah beberapa kegunaan biasa:

1. Tambahkan antara tatasusunan

var array1 = [12 , "foo" , {name "Joe"} , -2458]; 
var array2 = ["Doe" , 555 , 100]; 
Array.prototype.push.apply(array1, array2); 
/* array1 值为 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */

2. Dapatkan nilai maksimum dan minimum dalam tatasusunan

var numbers = [5, 458 , 120 , -215 ]; 
var maxInNumbers = Math.max.apply(Math, numbers),  //458
  maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458

Nombor itu sendiri tidak mempunyai kaedah maks, tetapi Matematik mempunyai kaedah, jadi kita boleh menggunakan kaedahnya dengan memanggil atau memohon.

3 Sahkan sama ada ia adalah tatasusunan (dengan syarat kaedah toString() belum ditindih)

functionisArray(obj){ 
  return Object.prototype.toString.call(obj) === '[object Array]' ;
}

4. Tatasusunan Kelas (pseudo) menggunakan kaedah tatasusunan

var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));

Terdapat struktur objek yang dipanggil tatasusunan pseudo dalam Javascript. Apa yang lebih istimewa ialah objek argumen, dan panggilan seperti getElementsByTagName, document.childNodes, dsb., yang mengembalikan objek NodeList ialah tatasusunan pseudo. Kaedah push, pop dan lain-lain di bawah Array tidak boleh digunakan.

Tetapi kita boleh menukarnya menjadi objek tatasusunan sebenar dengan sifat panjang melalui Array.prototype.slice.call, supaya domNodes boleh menggunakan semua kaedah di bawah Array.

Pemahaman mendalam tentang penggunaan apply dan call

Berikut ialah [meminjam soalan temu duga] untuk memahami memohon dan menghubungi dengan lebih mendalam.

Tentukan kaedah log supaya ia boleh memproksi kaedah console.log Penyelesaian biasa ialah:

function log(msg) {
 console.log(msg);
}
log(1);  //1
log(1,2);  //1

Kaedah di atas boleh menyelesaikan keperluan paling asas, tetapi apabila bilangan parameter yang dilalui tidak pasti, kaedah di atas tidak sah Pada masa ini, anda boleh mempertimbangkan untuk menggunakan permohonan atau panggilan Perhatikan berapa banyak parameter yang diluluskan di sini adalah tidak pasti, jadi sebaiknya gunakan cara berikut:

function log(){
 console.log.apply(console, arguments);
};
log(1);  //1
log(1,2);  //1 2

Keperluan seterusnya ialah menambah awalan "(aplikasi)" pada setiap mesej log, seperti:

log("hello world");  //(app)hello world

Bagaimana untuk melakukannya dengan lebih elegan? Pada masa ini, anda perlu berfikir bahawa parameter argumen ialah tatasusunan pseudo, menukarnya menjadi tatasusunan standard melalui Array.prototype.slice.call, dan kemudian gunakan kaedah tatasusunan nyahshift, seperti ini:

function log(){
 var args = Array.prototype.slice.call(arguments);
 args.unshift('(app)');
 console.log.apply(console, args);
};

ikat

Selepas bercakap tentang memohon dan menelefon, mari bercakap tentang bind. Kaedah bind() sangat serupa dengan memohon dan memanggil, dan juga boleh menukar penunjuk ini dalam badan fungsi.

Penjelasan MDN ialah: Kaedah bind() akan mencipta fungsi baharu, yang dipanggil fungsi binding Apabila fungsi mengikat ini dipanggil, fungsi mengikat akan berdasarkan nilai pertama yang dihantar ke kaedah bind() apabila ia dipanggil. dibuat. Parameternya ialah ini, dan parameter kedua dan seterusnya dihantar ke dalam kaedah bind() ditambah dengan parameter fungsi terikat itu sendiri apabila dijalankan digunakan mengikut urutan sebagai parameter fungsi asal untuk memanggil fungsi asal.

Mari kita lihat cara menggunakannya secara langsung Dalam mod tunggal biasa, kita biasanya menggunakan _ini, itu, diri, dll. untuk menyimpan ini supaya kita boleh terus merujuk kepadanya selepas menukar konteks. Seperti ini:

var foo = {
  bar : 1,
  eventBind: function(){
    var _this = this;
    $('.someClass').on('click',function(event) {
      /* Act on the event */
      console.log(_this.bar);   //1
    });
  }
}

由于 Javascript 特有的机制,上下文环境在 eventBind:function(){ } 过渡到 $('.someClass').on('click',function(event) { }) 发生了改变,上述使用变量保存 this 这些方式都是有用的,也没有什么问题。当然使用 bind() 可以更加优雅的解决这个问题:

var foo = {
  bar : 1,
  eventBind: function(){
    $('.someClass').on('click',function(event) {
      /* Act on the event */
      console.log(this.bar);   //1
    }.bind(this));
  }
}

在上述代码里,bind() 创建了一个函数,当这个click事件绑定在被调用的时候,它的 this 关键词会被设置成被传入的值(这里指调用bind()时传入的参数)。因此,这里我们传入想要的上下文 this(其实就是 foo ),到 bind() 函数中。然后,当回调函数被执行的时候, this 便指向 foo 对象。再来一个简单的栗子:

var bar = function(){
console.log(this.x);
}
var foo = {
x:3
}
bar(); // undefined
var func = bar.bind(foo);
func(); // 3

这里我们创建了一个新的函数 func,当使用 bind() 创建一个绑定函数之后,它被执行的时候,它的 this 会被设置成 foo , 而不是像我们调用 bar() 时的全局作用域。

有个有趣的问题,如果连续 bind() 两次,亦或者是连续 bind() 三次那么输出的值是什么呢?像这样:

var bar = function(){
  console.log(this.x);
}
var foo = {
  x:3
}
var sed = {
  x:4
}
var func = bar.bind(foo).bind(sed);
func(); //?
 
var fiv = {
  x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //?

答案是,两次都仍将输出 3 ,而非期待中的 4 和 5 。原因是,在Javascript中,多次 bind() 是无效的。更深层次的原因, bind() 的实现,相当于使用函数在内部包了一个 call / apply ,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。

   apply、call、bind比较

那么 apply、call、bind 三者相比较,之间又有什么异同呢?何时使用 apply、call,何时使用 bind 呢。简单的一个栗子:

var obj = {
  x: 81,
};
var foo = {
  getX: function() {
    return this.x;
  }
}
console.log(foo.getX.bind(obj)()); //81
console.log(foo.getX.call(obj));  //81
console.log(foo.getX.apply(obj));  //81

三个输出的都是81,但是注意看使用 bind() 方法的,他后面多了对括号。

也就是说,区别是,当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。

再总结一下:

apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
apply 、 call 、bind 三者都可以利用后续参数传参;

bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

好了,本文关于开启Javascript中apply、call、bind的用法之旅模式的相关教程,到此给大家介绍完了,希望大家喜欢。

Kenyataan:
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