成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

回味JS基礎(chǔ):call apply 與 bind

plokmju88 / 2431人閱讀

摘要:使用方法調(diào)用匿名函數(shù)在下例中的循環(huán)體內(nèi),我們創(chuàng)建了一個(gè)匿名函數(shù),然后通過(guò)調(diào)用該函數(shù)的方法,將每個(gè)數(shù)組元素作為指定的值執(zhí)行了那個(gè)匿名函數(shù)。這個(gè)匿名函數(shù)的主要目的是給每個(gè)數(shù)組元素對(duì)象添加一個(gè)方法,這個(gè)方法可以打印出各元素在數(shù)組中的正確索引號(hào)。

原文:回味JS基礎(chǔ):call apply 與 bind

在JavaScript中,call、applybindFunction對(duì)象自帶的三個(gè)方法,本文將通過(guò)幾個(gè)場(chǎng)景的應(yīng)用,來(lái)詳細(xì)理解三個(gè)方法。

call()

call() 方法在使用一個(gè)指定的this值和若干個(gè)指定的參數(shù)值的前提下調(diào)用某個(gè)函數(shù)或方法。

當(dāng)調(diào)用一個(gè)函數(shù)時(shí),可以賦值一個(gè)不同的 this 對(duì)象。this 引用當(dāng)前對(duì)象,即 call 方法的第一個(gè)參數(shù)。

通過(guò) call 方法,你可以在一個(gè)對(duì)象上借用另一個(gè)對(duì)象上的方法,比如Object.prototype.toString.call([]),就是一個(gè)Array對(duì)象借用了Object對(duì)象上的方法。

語(yǔ)法 fun.call(thisArg[, arg1[, arg2[, ...]]])

thisArg

在fun函數(shù)運(yùn)行時(shí)指定的this值。需要注意的是下面幾種情況

(1)不傳,或者傳null,undefined, 函數(shù)中的this指向window對(duì)象
(2)傳遞另一個(gè)函數(shù)的函數(shù)名,函數(shù)中的this指向這個(gè)函數(shù)的引用,并不一定是該函數(shù)執(zhí)行時(shí)真正的this
(3)值為原始值(數(shù)字,字符串,布爾值)的this會(huì)指向該原始值的自動(dòng)包裝對(duì)象,如 String、Number、Boolean
(4)傳遞一個(gè)對(duì)象,函數(shù)中的this指向這個(gè)對(duì)象

arg1, arg2, ...

指定的參數(shù)列表。

例子

初級(jí)應(yīng)用例子

function a(){
    //輸出函數(shù)a中的this對(duì)象
    console.log(this); 
}
//定義函數(shù)b
function b(){} 

var obj = {name:"這是一個(gè)屌絲"}; //定義對(duì)象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

使用call方法調(diào)用匿名函數(shù)并且指定上下文的this

在下面的例子中,當(dāng)調(diào)用 greet 方法的時(shí)候,該方法的 this 值會(huì)綁定到 i對(duì)象。

function greet() {
  var reply = [this.person, "是一個(gè)輕量的", this.role].join(" ");
  console.log(reply);
}

var i = {
  person: "JSLite.io", role: "Javascript 庫(kù)。"
};

greet.call(i); 
// JSLite.io 是一個(gè)輕量的 Javascript 庫(kù)。

使用call方法調(diào)用匿名函數(shù)

在下例中的for循環(huán)體內(nèi),我們創(chuàng)建了一個(gè)匿名函數(shù),然后通過(guò)調(diào)用該函數(shù)的call方法,將每個(gè)數(shù)組元素作為指定的this值執(zhí)行了那個(gè)匿名函數(shù)。這個(gè)匿名函數(shù)的主要目的是給每個(gè)數(shù)組元素對(duì)象添加一個(gè)print方法,這個(gè)print方法可以打印出各元素在數(shù)組中的正確索引號(hào)。當(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);
}
//#0 Lion: King
//#1 Whale: Fail

使用call方法調(diào)用函數(shù)傳參數(shù)

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 JSLite.io
//I"m function a!
apply()

語(yǔ)法與 call() 方法的語(yǔ)法幾乎完全相同,唯一的區(qū)別在于,apply的第二個(gè)參數(shù)必須是一個(gè)包含多個(gè)參數(shù)的數(shù)組(或類(lèi)數(shù)組對(duì)象)。apply的這個(gè)特性很重要,

在調(diào)用一個(gè)存在的函數(shù)時(shí),你可以為其指定一個(gè) this 對(duì)象。 this 指當(dāng)前對(duì)象,也就是正在調(diào)用這個(gè)函數(shù)的對(duì)象。 使用 apply, 你可以只寫(xiě)一次這個(gè)方法然后在另一個(gè)對(duì)象中繼承它,而不用在新對(duì)象中重復(fù)寫(xiě)該方法。

語(yǔ)法:fun.apply(thisArg[, argsArray])

注意: 需要注意:Chrome 14 以及 Internet Explorer 9 仍然不接受類(lèi)數(shù)組對(duì)象。如果傳入類(lèi)數(shù)組對(duì)象,它們會(huì)拋出異常。

參數(shù)

thisArg

同上callthisArg參數(shù)。

argsArray

一個(gè)數(shù)組或者類(lèi)數(shù)組對(duì)象,其中的數(shù)組元素將作為多帶帶的參數(shù)傳給 fun 函數(shù)。如果該參數(shù)的值為nullundefined,則表示不需要傳入任何參數(shù)。從ECMAScript 5 開(kāi)始可以使用類(lèi)數(shù)組對(duì)象。

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

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

使用apply來(lái)鏈接構(gòu)造器的例子

你可以使用apply來(lái)給一個(gè)對(duì)象鏈接構(gòu)造器,類(lèi)似于Java. 在接下來(lái)的例子中我們會(huì)創(chuàng)建一個(gè)叫做construct的全局的Function函數(shù),來(lái)使你能夠在構(gòu)造器中使用一個(gè)類(lèi)數(shù)組對(duì)象而非參數(shù)列表。

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"

使用apply和內(nèi)置函數(shù)

聰明的apply用法允許你在某些本來(lái)需要寫(xiě)成遍歷數(shù)組變量的任務(wù)中使用內(nèi)建的函數(shù)。在接下里的例子中我們會(huì)使用Math.max/Math.min來(lái)找出一個(gè)數(shù)組中的最大/最小值。

//里面有最大最小數(shù)字值的一個(gè)數(shù)組對(duì)象
var numbers = [5, 6, 2, 3, 7];

/* 使用 Math.min/Math.max 在 apply 中應(yīng)用 */
var max = Math.max.apply(null, numbers);
// 一般情況是用 Math.max(5, 6, ..) 或者 Math.max(numbers[0], ...) 來(lái)找最大值
var min = Math.min.apply(null, numbers);

//通常情況我們會(huì)這樣來(lái)找到數(shù)字的最大或者最小值
//比對(duì)上面的栗子,是不是下面的看起來(lái)沒(méi)有上面的舒服呢?
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];
}

參數(shù)數(shù)組切塊后循環(huán)傳入

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]);
bind

bind() 函數(shù)會(huì)創(chuàng)建一個(gè)新函數(shù)(稱(chēng)為綁定函數(shù))

bind是ES5新增的一個(gè)方法

傳參和call或apply類(lèi)似

不會(huì)執(zhí)行對(duì)應(yīng)的函數(shù),call或apply會(huì)自動(dòng)執(zhí)行對(duì)應(yīng)的函數(shù)

返回對(duì)函數(shù)的引用

語(yǔ)法 fun.bind(thisArg[, arg1[, arg2[, ...]]])

下面例子:當(dāng)點(diǎn)擊網(wǎng)頁(yè)時(shí),EventClick被觸發(fā)執(zhí)行,輸出JSLite.io p1 p2, 說(shuō)明EventClick中的thisbind改變成了obj對(duì)象。如果你將EventClick.bind(obj,"p1","p2") 變成 EventClick.call(obj,"p1","p2") 的話(huà),頁(yè)面會(huì)直接輸出 JSLite.io p1 p2

var obj = {name:"JSLite.io"};
/**
 * 給document添加click事件監(jiān)聽(tīng),并綁定EventClick函數(shù)
 * 通過(guò)bind方法設(shè)置EventClick的this為obj,并傳遞參數(shù)p1,p2
 */
document.addEventListener("click",EventClick.bind(obj,"p1","p2"),false);
//當(dāng)點(diǎn)擊網(wǎng)頁(yè)時(shí)觸發(fā)并執(zhí)行
function EventClick(a,b){
    console.log(
            this.name, //JSLite.io
            a, //p1
            b  //p2
    )
}
// JSLite.io p1 p2
兼容
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在這里指向的是目標(biāo)函數(shù)
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP
                 ? this //此時(shí)的this就是new出的obj
                 : oThis || this,//如果傳遞的oThis無(wú)效,就將fBound的調(diào)用者作為this
                
               //將通過(guò)bind傳遞的參數(shù)和調(diào)用時(shí)傳遞的參數(shù)進(jìn)行合并,并作為最終的參數(shù)傳遞
               aArgs.concat(Array.prototype.slice.call(arguments)));
        };
    fNOP.prototype = this.prototype;
    //將目標(biāo)函數(shù)的原型對(duì)象拷貝到新函數(shù)中,因?yàn)槟繕?biāo)函數(shù)有可能被當(dāng)作構(gòu)造函數(shù)使用
    fBound.prototype = new fNOP();
    //返回fBond的引用,由外部按需調(diào)用
    return fBound;
  };
}

兼容例子來(lái)源于:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility

應(yīng)用場(chǎng)景:繼承
function Animal(name,weight){
   this.name = name;
   this.weight = weight;
}
function Cat(){
    // 在call中將this作為thisArgs參數(shù)傳遞
    // Animal方法中的this就指向了Cat中的this
    // 所以Animal中的this指向的就是cat對(duì)象
    // 在Animal中定義了name和weight屬性,就相當(dāng)于在cat中定義了這些屬性
    // cat對(duì)象便擁有了Animal中定義的屬性,從而達(dá)到了繼承的目的
    Animal.call(this,"cat","50");
    //Animal.apply(this,["cat","50"]);
    this.say = function(){
       console.log("I am " + this.name+",my weight is " + this.weight);
    }
}
//當(dāng)通過(guò)new運(yùn)算符產(chǎn)生了cat時(shí),Cat中的this就指向了cat對(duì)象
var cat = new Cat();
cat.say();
//輸出=> I am cat,my weight is 50
原型擴(kuò)展

在原型函數(shù)上擴(kuò)展和自定義方法,從而不污染原生函數(shù)。例如:我們?cè)?Array 上擴(kuò)展一個(gè) forEach

function test(){
    // 檢測(cè)arguments是否為Array的實(shí)例
    console.log(
        arguments instanceof Array, //false
        Array.isArray(arguments)  //false
    );
    // 判斷arguments是否有forEach方法
    console.log(arguments.forEach); 
    // undefined
    // 將數(shù)組中的forEach應(yīng)用到arguments上
    Array.prototype.forEach.call(arguments,function(item){
        console.log(item); // 1 2 3 4
    });
}
test(1,2,3,4);

關(guān)注公眾號(hào)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78834.html

相關(guān)文章

  • JS函數(shù)的一些基礎(chǔ)知識(shí)

    摘要:為了更好的講解構(gòu)造函數(shù)原型原型鏈等,我們需要復(fù)習(xí)一下函數(shù)的一些基礎(chǔ)知識(shí)。閉包在復(fù)習(xí)了函數(shù)的相關(guān)基礎(chǔ)知識(shí)之后,我們終于可以進(jìn)入閉包。我們可以這樣理解閉包,首先,閉包是一個(gè)函數(shù),是一個(gè)什么樣子的函數(shù)呢是一個(gè)可以訪(fǎng)問(wèn)另一個(gè)函數(shù)中變量的函數(shù)。 為了更好的講解構(gòu)造函數(shù)、原型、原型鏈等,我們需要復(fù)習(xí)一下函數(shù)的一些基礎(chǔ)知識(shí)。接下來(lái),就讓我們一起回味一些JS的基礎(chǔ)知識(shí)點(diǎn)。 全局變量VS局部變量 簡(jiǎn)單粗...

    Ashin 評(píng)論0 收藏0
  • JS基礎(chǔ)篇--call、apply、bind方法詳解

    摘要:首先我們可以通過(guò)給目標(biāo)函數(shù)指定作用域來(lái)簡(jiǎn)單實(shí)現(xiàn)方法保存,即調(diào)用方法的目標(biāo)函數(shù)考慮到函數(shù)柯里化的情況,我們可以構(gòu)建一個(gè)更加健壯的這次的方法可以綁定對(duì)象,也支持在綁定的時(shí)候傳參。原因是,在中,多次是無(wú)效的。而則會(huì)立即執(zhí)行函數(shù)。 bind 是返回對(duì)應(yīng)函數(shù),便于稍后調(diào)用;apply 、call 則是立即調(diào)用 。 apply、call 在 javascript 中,call 和 apply 都是...

    lastSeries 評(píng)論0 收藏0
  • js 面試官想了解你有多理解call,apply,bind?

    摘要:返回值這段在下方應(yīng)用中有詳細(xì)的示例解析。回調(diào)函數(shù)丟失的解決方案綁定回調(diào)函數(shù)的指向這是典型的應(yīng)用場(chǎng)景綁定指向,用做回調(diào)函數(shù)。 showImg(https://segmentfault.com/img/remote/1460000019971331?w=1024&h=680); 函數(shù)原型鏈中的 apply,call 和 bind 方法是 JavaScript 中相當(dāng)重要的概念,與 this...

    wuaiqiu 評(píng)論0 收藏0
  • js基礎(chǔ)】之this,call,apply,bind

    摘要:的使用場(chǎng)景作為構(gòu)造函數(shù)執(zhí)行作為對(duì)象屬性執(zhí)行作為普通函數(shù)執(zhí)行。要在執(zhí)行時(shí)才能確認(rèn)值,定義時(shí)無(wú)法確認(rèn)改變上下文指向。 1.this this的使用場(chǎng)景: 1.作為構(gòu)造函數(shù)執(zhí)行; 2.作為對(duì)象屬性執(zhí)行; 3.作為普通函數(shù)執(zhí)行; 4.call apply bind。 this要在執(zhí)行時(shí)才能確認(rèn)值,定義時(shí)無(wú)法確認(rèn) var a = { name:A, fn:function()...

    khs1994 評(píng)論0 收藏0
  • 從一道面試題,到“我可能看了假源碼”

    摘要:返回的綁定函數(shù)也能使用操作符創(chuàng)建對(duì)象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。同時(shí),將第一個(gè)參數(shù)以外的其他參數(shù),作為提供給原函數(shù)的預(yù)設(shè)參數(shù),這也是基本的顆?;A(chǔ)。 今天想談?wù)勔坏狼岸嗣嬖囶},我做面試官的時(shí)候經(jīng)常喜歡用它來(lái)考察面試者的基礎(chǔ)是否扎實(shí),以及邏輯、思維能力和臨場(chǎng)表現(xiàn),題目是:模擬實(shí)現(xiàn)ES5中原生bind函數(shù)。也許這道題目已經(jīng)不再新鮮,部分讀者也會(huì)有思路來(lái)解答。社區(qū)上關(guān)于原生bind的研...

    Carson 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<