apply bind call 詳解 和 實際應用

帶你深刻理解js 中 apply bind call

  1. 網上有不少博客寫了這方面的文章, 可是最近又從新複習一下,作一下理解
  2. 寫了幾個例子幫助你們理解一下
  3. 在項目中的做用

做用

  1. 改變函數執行時的上下文
  2. 改變函數運行時的this指向

this 永遠指向最後調用它的那個對象

來理解一下 this 的做用域javascript

var name = "window";

    var dog = {
        name : "小黃"
        eat: function () {
            console.log(this.name)
        },
        say: function () {
            setTimeout(  function () {
                // 默認指向window對象,若是在嚴格模式下, 默認是undefined
                this.eat()
            },100);
        }
    };
    dog.say()   // this.eat is not a function
複製代碼

當 setTimeout 執行的時候 最後調用的 對象是 window, window 沒有 eat 的方法因此 出錯java

在寫一個例子理解一下 this 永遠指向最後調用它的那個對象 這句話windows

var name = "windows";
    var dog = {
        name: "小黃",
        say : function () {
            console.log(this.name);      // windows
        }
    }
    var fn = a.say;
    fn();
複製代碼

爲何 dog 做用域下 有 name 屬性, 還輸出了 全局的 name 呢數組

  1. this 永遠指向最後調用它的那個對象
  2. fn = a.say 並無執行 當 fn() 執行的時候 是 window 的做用域下

解決以上兩個問題

咱們這裏只拿一個 call修改做用域 解決這個問題數據結構

var name = "window";

    var dog = {
        name : "小黃"
        eat: function () {
            console.log(this.name)
        },
        say: function () {
            setTimeout(  function () {
                this.eat()
            }.call(dog),100);
        }
    };
    dog.say()   // this.eat is not a function
複製代碼

在調用的時候修改 this 的指向手動吧 this 指向 dog 的做用域app

現實場景中的應用

  1. 構造函數中 方法的公用dom

    function Animal (name){
            this.name = name
            this.food = food
        }
        Animal.prototype = {
            eay: function(){
                console.log(this.name + 'eat: ' + this.food)
            }
        }
        var dog = new Person('小黃''火腿')
        dog.eay()
    複製代碼

    上面代碼會輸出 小黃eat: 火腿函數

    var cat = {
        }
    複製代碼

    咱們定義了一個構造函數 那若是咱們有有一個對象也想使用 Animal 原型中 eay 的方法咋辦, 不能在從新寫一遍 eay 方法吧ui

    // 1 call
        person.showName.call(cat, '小貓咪''魚');
        // 2 apply
        person.showName.apply(cat, ['小貓咪''魚']);
        // 3 bind
        person.showName.bind(cat, '小貓咪''魚')();
    複製代碼

    具體的怎麼傳參, 他們的差異是啥 能夠看一下 MDN 上的文檔說明this

  2. 將僞數組轉化成 數組 arguments 也是僞數組 咱們知道在看 jq 的源碼中 常常經過 call apply 的 形式 轉換成真正的數組

    var element = {
            0: 'div',
            1: 'p',
            2: 'span',
            length: 3
        }
    複製代碼

    這裏必定要注意(數據結構必須是以數字爲下標並且必定要有length屬性 且必須是number類型) 你們能夠實際看一下 dom 的僞數組

    見證奇蹟的時刻

    // slice 能夠將 僞數組轉換成真正的數組
        var arr = Array.prototype.slice.call(element);
    複製代碼
  3. 求數組中的最大和最小值

    var arr = [34,5,3,6,54,6,-67,5,7,6,-8,687];
        // 數組沒有 max 的方法 可使用 Max 中的方法
        Math.max.apply(Math, arr);
    複製代碼
  4. 判斷變量類型

    function isArray(obj){
            return Object.prototype.toString.call(obj) == '[object Array]';
        }
        isArray([]) // true
        isArray('false') // false
    複製代碼
相關文章
相關標籤/搜索