Rumah  >  Artikel  >  hujung hadapan web  >  Penjelasan terperinci tentang kaedah memohon dan mengikat panggilan dalam pengetahuan javascript_Basic

Penjelasan terperinci tentang kaedah memohon dan mengikat panggilan dalam pengetahuan javascript_Basic

WBOY
WBOYasal
2016-05-16 15:11:251652semak imbas

Dalam JavaScript, panggil, gunakan dan ikat adalah tiga kaedah yang disertakan dengan objek Fungsi Artikel ini akan memahami tiga kaedah secara terperinci melalui aplikasi beberapa senario.

panggil()

Kaedah panggilan() memanggil fungsi atau kaedah menggunakan nilai ini yang ditentukan dan beberapa nilai parameter yang ditentukan.

Apabila memanggil fungsi, anda boleh menetapkan objek ini yang berbeza. ini merujuk kepada objek semasa, parameter pertama kaedah panggilan.

Melalui kaedah panggilan, anda boleh meminjam kaedah pada satu objek daripada objek lain, seperti Object.prototype.toString.call([]), iaitu kaedah peminjaman objek Array pada objek Objek.

Syntax fun.call(thisArg[, arg1[, arg2[, ...]]])
thisArg
Nilai ini ditentukan apabila fungsi menyeronokkan sedang berjalan. Apa yang anda perlu beri perhatian ialah situasi berikut

(1) Jangan lulus, atau lulus null atau undefined Ini dalam fungsi menghala ke objek tetingkap
(2) Lulus nama fungsi fungsi lain Ini dalam fungsi menunjuk kepada rujukan kepada fungsi ini, yang tidak semestinya nilai ini sebenar apabila fungsi itu dilaksanakan
(3) Ini yang nilainya adalah nilai primitif (nombor, rentetan, nilai Boolean) akan menunjukkan kepada objek pembungkusan automatik bagi nilai primitif, seperti String, Number, Boolean
(4) Lulus objek, dan ini dalam fungsi menghala ke objek ini

arg1, arg2, ...
Senarai parameter yang ditentukan.

Contoh
Contoh aplikasi asas

function a(){
 //输出函数a中的this对象
 console.log(this); 
}
//定义函数b
function b(){} 

var obj = {name:'这是一个屌丝'}; //定义对象obj
a.call(); //window
a.call(null); //window
a.call(undefined);//window
a.call(1); //Number
a.call(''); //String
a.call(true); //Boolean
a.call(b);// function b(){}
a.call(obj); //Object

Gunakan kaedah panggilan untuk memanggil fungsi tanpa nama dan nyatakan ini dalam konteks

Dalam contoh berikut, apabila kaedah salam dipanggil, nilai kaedah ini akan terikat pada objek i.

function greet() {
 var reply = [this.person, '是一个轻量的', this.role].join(' ');
 console.log(reply);
}

var i = {function greet() {
 var reply = [this.person, '是一个轻量的', this.role].join(' ');
 console.log(reply);
}

var i = {
 person: 'JSLite.io', role: 'Javascript 库。'
};

greet.call(i); 
// JSLite.io 是一个轻量的 Javascript 库。


 person: 'JSLite.io', role: 'Javascript 库。'
};

greet.call(i); 
// JSLite.io 是一个轻量的 Javascript 库。

Gunakan kaedah panggilan untuk memanggil fungsi tanpa nama

Dalam badan gelung for dalam contoh berikut, kami mencipta fungsi tanpa nama, dan kemudian melaksanakan fungsi tanpa nama dengan memanggil kaedah panggilan fungsi tersebut, menggunakan setiap elemen tatasusunan seperti yang dinyatakan nilai ini. Tujuan utama fungsi tanpa nama ini adalah untuk menambah kaedah cetakan pada setiap objek elemen tatasusunan ini boleh mencetak nombor indeks yang betul bagi setiap elemen dalam tatasusunan. Sudah tentu, ia tidak perlu untuk menghantar elemen tatasusunan ke dalam fungsi tanpa nama kerana nilai ini (parameter normal sudah mencukupi).

var animals = [
 {species: 'Lion', name: 'King'},
 {species: 'Whale', name: 'Fail'}
];

for (var i = 0; i < animals.length; i++) {
 (function (i) { 
 this.print = function () { 
  console.log('#' + i + ' ' + this.species + ': ' + this.name); 
 } 
 this.print();
 }).call(animals[i], i);
}
//#0 Lion: King
//#1 Whale: Fail

Gunakan kaedah panggilan untuk memanggil fungsi dan lulus parameter

var a = {
 name:'JSLite.io', //定义a的属性
 say:function(){ //定义a的方法
  console.log("Hi,I'm function a!");
 }
};
function b(name){
 console.log("Post params: "+ name);
 console.log("I'm "+ this.name);
 this.say();
}

b.call(a,'test');
//Post params: test
//I'm onepixel
//I'm function a!

mohon()

Sintaks hampir sama dengan kaedah call(), satu-satunya perbezaan ialah parameter kedua permohonan mestilah tatasusunan (atau objek seperti tatasusunan) yang mengandungi berbilang parameter. Ciri permohonan ini sangat penting,

Apabila memanggil fungsi sedia ada, anda boleh menentukan objek ini untuknya. ini merujuk kepada objek semasa, iaitu objek yang memanggil fungsi ini. Menggunakan apply, anda boleh menulis kaedah sekali dan kemudian mewarisinya dalam objek lain, tanpa perlu menulis kaedah berulang kali dalam objek baharu.

Sintaks: fun.apply(thisArg[, argsArray])
Nota: Adalah penting untuk ambil perhatian bahawa Chrome 14 dan Internet Explorer 9 masih tidak menerima objek seperti tatasusunan. Jika objek seperti tatasusunan dihantar masuk, mereka akan membuang pengecualian.

Parameter
thisArg

Sama seperti parameter thisArg bagi panggilan di atas.

argsArray

Suatu tatasusunan atau objek seperti tatasusunan, elemen tatasusunan yang akan dihantar sebagai parameter berasingan kepada fungsi yang menyeronokkan. Jika nilai parameter ini adalah batal atau tidak ditentukan, ini bermakna tiada parameter perlu dihantar. Bermula dari ECMAScript 5, objek seperti tatasusunan tersedia.

Contoh

function jsy(x,y,z){
 console.log(x,y,z);
}

jsy.apply(null,[1,2,3]); 
// 1 2 3

Contoh penggunaan apply to link constructor

Anda boleh menggunakan apply untuk memautkan pembina ke objek, serupa dengan Java Dalam contoh berikut, kami akan mencipta fungsi Fungsi global yang dipanggil konstruk untuk membolehkan anda menggunakan objek seperti tatasusunan dalam pembina dan bukannya senarai parameter. .

Function.prototype.construct = function(aArgs) {
 var fConstructor = this, 
 fNewConstr = function() { 
 fConstructor.apply(this, aArgs); 
 };
 fNewConstr.prototype = fConstructor.prototype;
 return new fNewConstr();
};
function MyConstructor () {
 for (var nProp = 0; nProp < arguments.length; nProp++) {
  console.log(arguments,this)
  this["property" + nProp] = arguments[nProp];
 }
}
var myArray = [4, "Hello world!", false];
var myInstance = MyConstructor.construct(myArray);

console.log(myInstance.property1);    // logs "Hello world!"
console.log(myInstance instanceof MyConstructor); // logs "true"
console.log(myInstance.constructor);    // logs "MyConstructor"

Gunakan aplikasi dan fungsi terbina dalam

Penggunaan penggunaan pintar membolehkan anda menggunakan fungsi terbina dalam dalam tugas tertentu yang sebaliknya akan ditulis sebagai lelaran ke atas pembolehubah tatasusunan. Dalam contoh berikut kita akan menggunakan Math.max/Math.min untuk mencari nilai maksimum/minimum dalam tatasusunan.

//里面有最大最小数字值的一个数组对象
var numbers = [5, 6, 2, 3, 7];

/* 使用 Math.min/Math.max 在 apply 中应用 */
var max = Math.max.apply(null, numbers);
// 一般情况是用 Math.max(5, 6, ..) 或者 Math.max(numbers[0], ...) 来找最大值
var min = Math.min.apply(null, numbers);

//通常情况我们会这样来找到数字的最大或者最小值
//比对上面的栗子,是不是下面的看起来没有上面的舒服呢?
max = -Infinity, min = +Infinity;
for (var i = 0; i < numbers.length; i++) {
 if (numbers[i] > max)
 max = numbers[i];
 if (numbers[i] < min) 
 min = numbers[i];
}

Susun atur parameter dipotong menjadi kepingan dan dihantar dalam gelung

function minOfArray(arr) {
 var min = Infinity;
 var QUANTUM = 32768;

 for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
 var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
 console.log(submin, min)
 min = Math.min(submin, min);
 }

 return min;
}

var min = minOfArray([5, 6, 2, 3, 7]);


ikat

Fungsi bind() mencipta fungsi baharu (dipanggil fungsi terikat)

bind ialah kaedah baharu dalam ES5
Melepasi parameter adalah serupa dengan memanggil atau memohon
Fungsi yang sepadan tidak akan dilaksanakan, memanggil atau memohon akan secara automatik melaksanakan fungsi yang sepadan
Mengembalikan rujukan kepada fungsi
Syntax fun.bind(thisArg[, arg1[, arg2[, ...]]])

Contoh berikut: Apabila halaman web diklik, EventClick dicetuskan dan dilaksanakan, dan JSLite.io p1 p2 adalah output, menunjukkan bahawa ini dalam EventClick telah ditukar menjadi objek obj melalui bind. Jika anda menukar EventClick.bind(obj,'p1','p2') kepada EventClick.call(obj,'p1','p2'), halaman tersebut akan terus mengeluarkan JSLite.io p1 p2

var obj = {name:'JSLite.io'};
/**
 * 给document添加click事件监听,并绑定EventClick函数
 * 通过bind方法设置EventClick的this为obj,并传递参数p1,p2
 */
document.addEventListener('click',EventClick.bind(obj,'p1','p2'),false);
//当点击网页时触发并执行
function EventClick(a,b){
 console.log(
   this.name, //JSLite.io
   a, //p1
   b //p2
 )
}
// JSLite.io p1 p2

Serasi

if (!Function.prototype.bind) {
 Function.prototype.bind = function (oThis) {
 if (typeof this !== "function") {
  // closest thing possible to the ECMAScript 5
  // internal IsCallable function
  throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
 }

 var aArgs = Array.prototype.slice.call(arguments, 1), 
  fToBind = this, // this在这里指向的是目标函数
  fNOP = function () {},
  fBound = function () {
   return fToBind.apply(this instanceof fNOP
     &#63; this //此时的this就是new出的obj
     : oThis || this,//如果传递的oThis无效,就将fBound的调用者作为this
    
    //将通过bind传递的参数和调用时传递的参数进行合并,并作为最终的参数传递
    aArgs.concat(Array.prototype.slice.call(arguments)));
  };
 fNOP.prototype = this.prototype;
 //将目标函数的原型对象拷贝到新函数中,因为目标函数有可能被当作构造函数使用
 fBound.prototype = new fNOP();
 //返回fBond的引用,由外部按需调用
 return fBound;
 };
}

兼容例子来源于:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility

应用场景:继承

function Animal(name,weight){
 this.name = name;
 this.weight = weight;
}
function Cat(){
 // 在call中将this作为thisArgs参数传递
 // Animal方法中的this就指向了Cat中的this
 // 所以Animal中的this指向的就是cat对象
 // 在Animal中定义了name和weight属性,就相当于在cat中定义了这些属性
 // cat对象便拥有了Animal中定义的属性,从而达到了继承的目的
 Animal.call(this,'cat','50');
 //Animal.apply(this,['cat','50']);
 this.say = function(){
  console.log("I am " + this.name+",my weight is " + this.weight);
 }
}
//当通过new运算符产生了cat时,Cat中的this就指向了cat对象
var cat = new Cat();
cat.say();
//输出=> I am cat,my weight is 50

原型扩展

在原型函数上扩展和自定义方法,从而不污染原生函数。例如:我们在 Array 上扩展一个 forEach

function test(){
 // 检测arguments是否为Array的实例
 console.log(
  arguments instanceof Array, //false
  Array.isArray(arguments) //false
 );
 // 判断arguments是否有forEach方法
 console.log(arguments.forEach); 
 // undefined
 // 将数组中的forEach应用到arguments上
 Array.prototype.forEach.call(arguments,function(item){
  console.log(item); // 1 2 3 4
 });
}
test(1,2,3,4);

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