欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談javascript的call()、apply()、bind()的用法

 更新時間:2016年02月21日 14:35:34   作者:景莊  
這篇文章主要為大家詳細介紹了javascript的call()、apply()、bind()的用法,探討JavaScript中函數(shù)的一些特殊用法,感興趣的小伙伴們可以參考一下

JavaScript中的函數(shù)不僅是一種類似于Java中方法的語言功能,它還可以作為對象而存在。 本文將要探討JavaScript中函數(shù)的一些特殊用法,包括call、apply、bind三個原型方法。
一、函數(shù)基礎(chǔ)
JavaScript中的函數(shù)是一種類似于Java中方法的語言功能,不過它可以獨立于類進行定義。

函數(shù)式編程:由于JavaScript支持匿名函數(shù),因此可以將函數(shù)作為對象來使用, 所以JavaScript不僅支持過程式編程(面向?qū)ο笠彩沁^程式編程的一種),還支持函數(shù)式編程。
上下文

函數(shù)的每次調(diào)用都會擁有一個特殊值——本次調(diào)用的上下文(context)——這就是this關(guān)鍵字的值。 如果函數(shù)掛載在一個對象上,作為對象的一個屬性,就稱它為對象的方法。當通過這個對象來調(diào)用函數(shù)時,該對象就是此次調(diào)用的上下文, 也就是該函數(shù)的this的值。

需要注意,this是一個關(guān)鍵字,不是變量,也不是屬性名。JavaScript的語法不允許給this賦值。

函數(shù)是一種對象

JavaScript中的函數(shù)和Java中的方法或C語言中的函數(shù)最大不同在于,JavaScript中的函數(shù)也是一種對象。 但這并不意味著,所有的對象都是函數(shù)。函數(shù)是一種包含了可執(zhí)行代碼,并能夠被其他代碼調(diào)用的特殊的對象。

和變量不同,關(guān)鍵字this沒有作用域的限制,嵌套的函數(shù)不會從調(diào)用它的函數(shù)中繼承this。 - 如果嵌套函數(shù)作為方法調(diào)用,其this的值指向調(diào)用它的對象。 - 如果嵌套函數(shù)作為函數(shù)調(diào)用,其this的值不是全局對象(非嚴格模式下)就是undefined(嚴格模式下)。

很多人誤以為調(diào)用嵌套函數(shù)時this會指向掉i用外層函數(shù)的上下文。如果你想訪問這個外部函數(shù)的this值, 需要將this的值保存都在一個變量中,這個變量和內(nèi)部函數(shù)都同在一個作用域內(nèi)。例如:

var o = {
 m: function() {
  var self = this;
  console.log(this==o); // true
  f();
  
  function f() {
   console.log(this === o); // false,this的值是全局對象或undefined
   console.log(self === o); // true
  }
 }
}

閉包

JavaScript的函數(shù)可以嵌套在其他函數(shù)中定義,這樣它們就可以訪問它們被定義時所處的作用域中的任何變量。 這意味著JavaScript函數(shù)構(gòu)成了一個閉包(closure),它給JavaScript帶來了非常強勁的編程能力。

作為值的函數(shù)
在JavaScript中,函數(shù)不僅是一種語法,也是值,也就是說,可以將函數(shù)賦值給變量,存儲在對象的屬性或數(shù)組的元素中, 作為參數(shù)傳入另外一個函數(shù)等。

bind、call、apply
每一個函數(shù)都包含一個prototype屬性,這個屬性是指向一個對象的引用,這個對象稱作“原型對象”。 每一個函數(shù)都包含不同的原型對象。當將函數(shù)用作構(gòu)造函數(shù)的時候,新創(chuàng)建的對象會從原型對象上繼承屬性。

Function.prototype.call()Function.prototype.apply()

call()和apply()可以看作為某個對象的方法,通過調(diào)用方法的形式來間接調(diào)用函數(shù)。 它們的第一個參數(shù)是要調(diào)用函數(shù)的母對象,它是調(diào)用上下文,在函數(shù)體內(nèi)通過this來獲得對它的引用。 apply()方法和call()方法的作用相同,只不過函數(shù)傳遞的方式不一樣,它的實參都放入在一個數(shù)組中。

舉個例子,以對象o的方法的形式調(diào)用函數(shù)f(),并傳入兩個參數(shù),可以使用這樣的代碼:

var o = {};

function f(a, b) {
 return a + b;
}

f.call(o, 1, 2);    // 將函數(shù)f作為o的方法,實際上就是重新設(shè)置函數(shù)f的上下文
f.apply(o, [1, 2]);

再舉一個例子,使用call方法調(diào)用匿名函數(shù):

在下例中的for循環(huán)體內(nèi),我們創(chuàng)建了一個匿名函數(shù),然后通過調(diào)用該函數(shù)的call方法,將每個數(shù)組元素作為指定的this值執(zhí)行了那個匿名函數(shù)。 這個匿名函數(shù)的主要目的是給每個數(shù)組元素對象添加一個print方法,這個print方法可以打印出各元素在數(shù)組中的正確索引號。 當然,這里不是必須得讓數(shù)組元素作為this值傳入那個匿名函數(shù)(普通參數(shù)就可以),目的是為了演示call的用法。

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);
}

Function.prototype.bind()

bind()是在ES5中新增的方法,從名字可以看出,這個方法的主要作用就是將函數(shù)綁定到某個對象。 當在函數(shù)f()上調(diào)用bind()方法并后竄入一個對象o作為參數(shù),這個方法將返回一個新函數(shù): (以函數(shù)調(diào)用的方式)調(diào)用新的函數(shù)將會把原始的函數(shù)f()作為o的方法來調(diào)用。例如:

function f(y) {
 return this.x + y;
}

var o = {
 x: 1
};

var g = f.bind(o); // 通過調(diào)用 g(x) 來調(diào)用 o.f(x)
g(2); // 3

其實我們可以輕松的實現(xiàn)bind()方法:

// 返回一個函數(shù),通過調(diào)用它來調(diào)用o中的方法f(),傳遞它所有的實參
function bind(f, o) {
 if (f.bind) return f.bind(o); // 如果bind()方法存在,使用bind()方法
 else return function () {
  return f.apply(o, arguments);
 }
}

二、函數(shù)式編程
JavaScript并非函數(shù)式編程語言,但在JavaScript中可以像操控對象一樣操控函數(shù),也就是說可以在JavaScript中應用函數(shù)式編程技術(shù)。

使用函數(shù)處理數(shù)組

假設(shè)有一個數(shù)組,數(shù)組元素都是數(shù)字,我們想要計算這些元素的平均值和標準差。

var data = [1, 1, 3, 5, 5];
var sum = function(x, y) {
 return x + y;
};
var square = function(x) {
 return x * x;
};

var mean = data.reduce(sum)/data.length;
var deviations = data.map(x => x - mean);

var stddev = Math.sqrt(deviations.map(square).reduce(sum)/(data.length - 1));
高階函數(shù)

高階函數(shù)就是操作函數(shù)的函數(shù),它接收一個或多個函數(shù)作為參數(shù),并返回一個新函數(shù)。舉個例子:

function not(f) {
 return function () {
  var result = f.apply(this, arguments);
  return !result;
 };
}

// 判斷x是否為偶數(shù)的函數(shù)
var even = function(x) {
 return x % 2 === 0;
};

var odd = not(even);      // 一個新函數(shù),所做的事情和even()相反
[1, 1, 3, 5, 5].every(odd);   // true,每個函數(shù)都是奇數(shù)

函數(shù)not()是個高階函數(shù),因為它返回一個新的函數(shù),這個新函數(shù)將它的實參傳入f(),并返回f的返回值的邏輯非。

以上就是關(guān)于javascript的call()、apply()、bind()的用法,希望對大家的學習有所幫助。

相關(guān)文章

  • 詳解Javascript繼承的實現(xiàn)

    詳解Javascript繼承的實現(xiàn)

    這篇文章主要介紹了詳解Javascript繼承的實現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • 微信小程序批量監(jiān)聽輸入框?qū)Π粹o樣式進行控制的實現(xiàn)代碼

    微信小程序批量監(jiān)聽輸入框?qū)Π粹o樣式進行控制的實現(xiàn)代碼

    這篇文章主要介紹了小程序批量監(jiān)聽輸入框?qū)Π粹o樣式進行控制的實現(xiàn)代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • 微信小程序?qū)崿F(xiàn)發(fā)送驗證碼按鈕效果

    微信小程序?qū)崿F(xiàn)發(fā)送驗證碼按鈕效果

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)發(fā)送驗證碼按鈕效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • 徹底理解JavaScript的原型與原型鏈

    徹底理解JavaScript的原型與原型鏈

    原型和原型鏈是js中的難點也是重點,明白了原型和原型鏈會讓我們在后面不管是學習還是工作都會更加高效,這篇文章主要給大家介紹了關(guān)于JavaScript原型與原型鏈的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • JavaScript利用Canvas實現(xiàn)粒子動畫倒計時

    JavaScript利用Canvas實現(xiàn)粒子動畫倒計時

    粒子動畫就是頁面上通過發(fā)射許多微小粒子來表示不規(guī)則模糊物體。本文將利用canvas實現(xiàn)酷炫的粒子動畫倒計時,感興趣的小伙伴可以嘗試一下
    2022-12-12
  • JavaScript如何實現(xiàn)組合列表框中元素移動效果

    JavaScript如何實現(xiàn)組合列表框中元素移動效果

    在頁面中有兩個列表框,需要把其中一個列表框的元素移動到另一個列表框,怎么實現(xiàn)此功能呢,下面通過本文給大家介紹JavaScript如何實現(xiàn)組合列表框中元素移動效果,感興趣的朋友一起學習吧
    2016-03-03
  • JavaScript調(diào)試之console.log調(diào)試的一個小技巧分享

    JavaScript調(diào)試之console.log調(diào)試的一個小技巧分享

    日常開發(fā)中經(jīng)常會需要console來查看當前對象的值。當然用debugger會更全面的查看,但是總有只喜歡用console的,比如我。下面這篇文章主要給大家分享了關(guān)于JavaScript調(diào)試之console.log調(diào)試的一個小技巧,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-08-08
  • javaScript把其它類型轉(zhuǎn)換為Number類型

    javaScript把其它類型轉(zhuǎn)換為Number類型

    在本篇文章里小編給大家整理的是關(guān)于javaScript把其它類型轉(zhuǎn)換為Number類型的相關(guān)文章,有需要的朋友們學習下。
    2019-10-10
  • 利用uni-app生成微信小程序的踩坑記錄

    利用uni-app生成微信小程序的踩坑記錄

    uni-app是一個使用 Vue.js 開發(fā)所有前端應用的框架,開發(fā)者編寫一套代碼,可發(fā)布到iOS、Android、H5、以及各種小程序(微信/支付寶/百度/頭條/QQ/釘釘)等多個平臺,這篇文章主要給大家介紹了關(guān)于利用uni-app生成微信小程序的踩坑記錄,需要的朋友可以參考下
    2022-04-04
  • 前端在WebSocket中加入Token的解決方式

    前端在WebSocket中加入Token的解決方式

    這篇文章主要給大家介紹了關(guān)于前端在WebSocket中加入Token的解決方式,文中提供了3種解決方法,對大家學習或者使用WebSocket具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-10-10

最新評論