JS基础 —— call、apply 和 bind

  • 函数的三个原型方法
  • 作用:改变this指向

call

MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call

  • 语法:function.call(thisArg[, arg1[, arg2[, ...]]])
    • function:待执行的方法
    • thisArg:待绑定的对象(可选,未指定时默认全局对象,严格模式下是undefined
    • [, arg1[, arg2[, ...]]]:任意个参数,提供给function的参数列表(可选,apply是参数数组
  • 简单模拟实现:将待执行的方法变成待绑定对象的方法,待执行完后,从对象中删除。
    var name = "obj3";
    var obj = {
        name: "obj",
        fun: function(x){
                console.log("x = "+x); // 测试传参
                return this.name; // 测试返回值
            }
        };
    var obj2 = { name: "obj2" };

    Function.prototype.myCall = function(obj){
	obj = obj || window;
	obj.fn = this;
	var args = [...arguments].slice(1); // 注意:arguments是类数组,不是数组
	var result = obj.fn(...args);
	delete obj.fn;
	return result;
    }
    
    console.log(obj.fun(1));
    console.group('== myCall ==');
        console.log(obj.fun.myCall(obj2,2));
        console.log(obj.fun.myCall());
    console.groupEnd();
    console.group('== call ==');
        console.log(obj.fun.call(obj2,2));
        console.log(obj.fun.call());
    console.groupEnd();
    // 输出
    x = 1
    obj
    == myCall ==
      x = 2
      obj2
      x = undefined
      obj3
    == call ==
      x = 2
      obj2
      x = undefined
      obj3

apply

MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

  • 同call,差别在第二个参数,call是参数列表,apply是参数数组

bind

MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

  • 语法:function.bind(thisArg[, arg1[, arg2[, ...]]])
  • 用法:
- 使一个函数(无论如何调用)都具有特定的this值
var obj = {
    name: "Tom"
};
function sayName(){
    console.log(this.name);
};
var fn = sayName.bind(obj);
fn();
// 输出
Tom
- 使函数具有预先指定的初始参数
function add(a,b){
    console.log(...arguments);
    return a+b;
}
var add23 = add.bind(null, 23);

console.log(add23(5));
console.log(add23(5,10));
// 输出
23,5
28
23,5,10
28 //会忽略之后多余的参数10

etc.

  • 简单模拟实现:返回一个绑定了上下文的函数
var o = {
    name: "Tom"
};
function sayName(){
    console.log(this.name);
}
			
Function.prototype.myBind = function(obj){
    obj = obj || window;
    var _this = this;
    var args = [...arguments].slice(1);
    return function(){
        _this.call(obj,args);
    }
}
			
var fn1 = sayName.bind(o);
var fn2 = sayName.myBind(o);

console.log(fn1());
console.log(fn2());
// 输出
Tom
undefined
Tom
undefined
posted on 2019-11-20 15:40  亭早  阅读(118)  评论(0)    收藏  举报