最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

需要注意,this是一個(gè)關(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的值不是全局對象(非嚴(yán)格模式下)就是undefined(嚴(yán)格模式下)。

很多人誤以為調(diào)用嵌套函數(shù)時(shí)this會指向掉i用外層函數(shù)的上下文。如果你想訪問這個(gè)外部函數(shù)的this值, 需要將this的值保存都在一個(gè)變量中,這個(gè)變量和內(nèi)部函數(shù)都同在一個(gè)作用域內(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ù)中定義,這樣它們就可以訪問它們被定義時(shí)所處的作用域中的任何變量。 這意味著JavaScript函數(shù)構(gòu)成了一個(gè)閉包(closure),它給JavaScript帶來了非常強(qiáng)勁的編程能力。

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

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

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

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

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

var o = {};

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

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

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

在下例中的for循環(huán)體內(nèi),我們創(chuàng)建了一個(gè)匿名函數(shù),然后通過調(diào)用該函數(shù)的call方法,將每個(gè)數(shù)組元素作為指定的this值執(zhí)行了那個(gè)匿名函數(shù)。 這個(gè)匿名函數(shù)的主要目的是給每個(gè)數(shù)組元素對象添加一個(gè)print方法,這個(gè)print方法可以打印出各元素在數(shù)組中的正確索引號。 當(dāng)然,這里不是必須得讓數(shù)組元素作為this值傳入那個(gè)匿名函數(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中新增的方法,從名字可以看出,這個(gè)方法的主要作用就是將函數(shù)綁定到某個(gè)對象。 當(dāng)在函數(shù)f()上調(diào)用bind()方法并后竄入一個(gè)對象o作為參數(shù),這個(gè)方法將返回一個(gè)新函數(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

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

// 返回一個(gè)函數(shù),通過調(diào)用它來調(diào)用o中的方法f(),傳遞它所有的實(shí)參
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中應(yīng)用函數(shù)式編程技術(shù)。

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

假設(shè)有一個(gè)數(shù)組,數(shù)組元素都是數(shù)字,我們想要計(jì)算這些元素的平均值和標(biāo)準(zhǔn)差。

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ù),它接收一個(gè)或多個(gè)函數(shù)作為參數(shù),并返回一個(gè)新函數(shù)。舉個(gè)例子:

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);      // 一個(gè)新函數(shù),所做的事情和even()相反
[1, 1, 3, 5, 5].every(odd);   // true,每個(gè)函數(shù)都是奇數(shù)

函數(shù)not()是個(gè)高階函數(shù),因?yàn)樗祷匾粋€(gè)新的函數(shù),這個(gè)新函數(shù)將它的實(shí)參傳入f(),并返回f的返回值的邏輯非。

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

相關(guān)文章

  • 有關(guān)Promises異步問題詳解

    有關(guān)Promises異步問題詳解

    這篇文章主要介紹了有關(guān)JavaScript Promises異步問題詳解的相關(guān)資料,需要的朋友可以參考下
    2015-11-11
  • JavaScript頁面實(shí)時(shí)顯示當(dāng)前時(shí)間實(shí)例代碼

    JavaScript頁面實(shí)時(shí)顯示當(dāng)前時(shí)間實(shí)例代碼

    最近因?yàn)轫?xiàng)目需要,有個(gè)需求是讓實(shí)時(shí)顯示當(dāng)前時(shí)間,然后想想這不簡單嗎,自己就動(dòng)手敲代碼,但是發(fā)現(xiàn)一個(gè)問題,通過getMonth()得到月份,總是會比當(dāng)前月份少1,深深覺得實(shí)踐出真知啊…之前覺得Date對象挺簡單的,有很多細(xì)節(jié)都沒有注意。下面這篇文章就給大家詳細(xì)介紹下。
    2016-10-10
  • JavaScript如何獲取父級元素和子級元素代碼示例

    JavaScript如何獲取父級元素和子級元素代碼示例

    最近工作中總遇到取各種父啊子啊,每次都得查,所以下面這篇文章主要給大家介紹了關(guān)于JavaScript如何獲取父級元素和子級元素的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • 詳解JavaScript的流程控制語句

    詳解JavaScript的流程控制語句

    這篇文章主要介紹了JavaScript的流程控制語句,感興趣的小伙伴們可以參考一下
    2015-11-11
  • JavaScript實(shí)現(xiàn)伸縮二級菜單

    JavaScript實(shí)現(xiàn)伸縮二級菜單

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)伸縮二級菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • js實(shí)現(xiàn)鼠標(biāo)懸浮給圖片加邊框的方法

    js實(shí)現(xiàn)鼠標(biāo)懸浮給圖片加邊框的方法

    這篇文章主要介紹了js實(shí)現(xiàn)鼠標(biāo)懸浮給圖片加邊框的方法,涉及jquery.insetborder.js中borderEffect方法的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-01-01
  • JavaScript實(shí)現(xiàn)的聯(lián)動(dòng)菜單特效示例

    JavaScript實(shí)現(xiàn)的聯(lián)動(dòng)菜單特效示例

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)的聯(lián)動(dòng)菜單特效,涉及javascript事件響應(yīng)及頁面元素屬性動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-07-07
  • 微信小程序全局變量功能與用法詳解

    微信小程序全局變量功能與用法詳解

    這篇文章主要介紹了微信小程序全局變量功能與用法,結(jié)合實(shí)例形式詳細(xì)分析了微信小程序全局變量的作用、定義、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-01-01
  • Javascript學(xué)習(xí)筆記 delete運(yùn)算符

    Javascript學(xué)習(xí)筆記 delete運(yùn)算符

    關(guān)于javascript的delete運(yùn)算符,MDN里有相關(guān)文檔。以下是我的學(xué)習(xí)筆記,更多是要關(guān)注特殊情況的使用和注意點(diǎn)。
    2011-09-09
  • 跟我學(xué)習(xí)javascript的異步腳本加載

    跟我學(xué)習(xí)javascript的異步腳本加載

    跟我學(xué)習(xí)javascript的異步腳本加載,告訴大家如何使自己的站點(diǎn)更快捷,以及最簡單的方法 利用什么樣的工具達(dá)到預(yù)期效果,想一探究竟的朋友可以參考一下這篇文章。
    2015-11-11

最新評論

康马县| 抚顺县| 和平县| 威海市| 麻阳| 庐江县| 年辖:市辖区| 南投县| 荆州市| 南昌县| 伊宁市| 会昌县| 商南县| 游戏| 宁德市| 会昌县| 东平县| 东阿县| 孝昌县| 桐梓县| 陕西省| 嘉峪关市| 吉木萨尔县| 舟曲县| 徐汇区| 宁阳县| 兰坪| 隆尧县| 南投市| 邹平县| 临桂县| 广东省| 临猗县| 昌江| 新巴尔虎右旗| 临夏市| 建昌县| 子长县| 中阳县| 溧水县| 故城县|