1. 程式人生 > >js進階二

js進階二

apply\call

apply和call可以改變this的指向

function f1(x, y) {
    console.log("結果是:" + (x + y) + this);
    return "10000";
  }
  f1(10, 20);//函式的呼叫
  window.f1(10, 20);


  var r1 = f1.apply(null, [1, 2]);//此時f1中的this是window
  console.log(r1);

  var r2 = f1.call(null, 1, 2);//此時f1中的this是window
  console.log(r2);

  var obj = {
    age: 10,
    sex: "男"
  };

  window.f1.apply(obj, [10, 20]);
  window.f1.call(obj, 10, 20);

輸出如下:

結果是:30[object Window]
結果是:30[object Window]

結果是:3[object Window]
10000

結果是:3[object Window]
10000

結果是:30[object Object]
結果是:30[object Object]

我們在來看一個例子

function Person(age,sex) {
      this.age=age;
      this.sex=sex;
    }
    //通過原型新增方法
    Person.prototype.sayHi=function (x,y) {
      console.log("您好啊:"+this.sex);
      return 1000;
    };
    var per=new Person(10,"男");
    per.sayHi();

    console.log("==============");
    function Student(name,sex) {
      this.name=name;
      this.sex=sex;
    }
    var stu=new Student("小明","人妖");
    var r1=per.sayHi.apply(stu,[10,20]);
    var r2=per.sayHi.call(stu,10,20);

    console.log(r1);
    console.log(r2);

輸出如下:

您好啊:男
==============
您好啊:人妖
您好啊:人妖
1000
1000

函式也是物件

    function f1() {
      console.log(this+":====>呼叫了");
    }
    //f1是函式,f1也是物件
    console.dir(f1);
    //物件呼叫方法,說明,該物件中有這個方法
    f1.apply();
    f1.call();
    console.log(f1.__proto__==Function.prototype);

輸出如下:

ƒ f1()
[object Window]:====>呼叫了
[object Window]:====>呼叫了
true

bind

複製了一份的時候,把引數傳入到了f1函式中,x===>10,y===>20,null就是this,預設就是window bind方法是複製的意思,引數可以在複製的時候傳進去,也可以在複製之後呼叫的時候傳入進去 apply和call是呼叫的時候改變this指向 bind方法,是賦值一份的時候,改變了this的指向



  function f1(x, y) {
    console.log((x + y) + ":=====>" + this.age,this);
  }

  var ff = f1.bind(null);
  ff(10, 20);

  //person物件
  function Person() {
    this.age = 1000;
  }
  Person.prototype.eat = function () {
    console.log("這個是吃");
  };
  var per = new Person();
  //傳遞person例項物件
  var ff = f1.bind(per, 10, 20);
  ff();

結果輸出如下:

30:=====>undefined Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
30:=====>1000 Person {age: 1000}

匿名函式返回值

function File(name, size, time) {
      this.name = name;//電影名字
      this.size = size;//電影大小
      this.time = time;//電影的上映時間
    }
    var f1 = new File("jack.avi", "400M", "1997-12-12");
    var f2 = new File("tom.avi", "200M", "2017-12-12");
    var f3 = new File("xiaosu.avi", "800M", "2010-12-12");
    var f4 = new File("xiaosu.bvi", "800M", "2010-12-12");
    var arr = [f3,f4,f1, f2, ];

    function fn(attr) {
      //函式作為返回值
      return function getSort(obj1, obj2) {
        if (obj1[attr] > obj2[attr]) {
          return 1;
        } else if (obj1[attr] == obj2[attr]) {
          return 0;
        } else {
          return -1;
        }
      }
    }

    var ff = fn("name");

    //函式作為引數
    arr.sort(ff);
    for (var i = 0; i < arr.length; i++) {
      console.log(arr[i].name + "====>" + arr[i].size + "===>" + arr[i].time);
    }

輸出如下:

jack.avi====>400M===>1997-12-12
tom.avi====>200M===>2017-12-12
xiaosu.avi====>800M===>2010-12-12
xiaosu.bvi====>800M===>2010-12-12

閉包

閉包可以快取資料

 //普通的函式
  function f1() {
      var num = 10;
      num++;
      return num;
    }
    console.log(f1());
    console.log(f1());
    console.log(f1());

    //函式模式的閉包
    function f2() {
      var num = 10;
      return function () {
        num++;
        return num;
      }
    }
    var ff = f2();
    console.log(ff());//11
    console.log(ff());//12
    console.log(ff());//13

輸出如下:

11
11
11
11
12
13

閉包