JS中call,apply,bind方法

红叶何时落水

bind是函数原型对象上的一个方法,用于改变函数的this指向

这个方法会返回一个新函数,新函数可以调用他所绑定的对象的属性。 

var name = 'window';
var newThis = { name: 'newThis' };
var showName = (info1, info2) => {
    console.log(this, info1, info2);
}
showName('a', 'b'); 

// 通过bind改变this指向
var newShowName = showName.bind(newThis, 'hello', 'world');
showName = (info1, info2) => {
    console.log('new_func');
}
newShowName(); 

showName('a', 'b');


输出

Window {window: Window, self: Window, document: #document, name: 'window', location: Location, …} a b
Window {window: Window, self: Window, document: #document, name: 'window', location: Location, …} hello world
new_func

bind方法的简易实现

    Function.prototype.bind = function (o) {

        var self = this, boundArgs = arguments;//bind()方法的返回值是一个函数

        return function () {//创建一个实参列表,将传入bind()的第二个及后续的实参都传入这个函数
            var args = [], i;
            for (i = 1; i < boundArgs.length; i++)args.push(boundArgs[i]);
            return self.apply(o, args);
        };
    };

再者,bind会返回一个新函数,那么就可以蕴含了柯里化的思想,将一些参数的值固定。

var newThis = { name: '可通过改变对象属性改变' };
function showName(info1, info2) {
    console.log(this.name, info1, info2);
}

var newShowName = showName.bind(newThis, '外部无法改变,属于该函数不可改变的私有变量');
newShowName('新函数的实参');

newThis.name = '对象属性改变';

newShowName('新函数的实参');

输出

可通过改变对象属性改变 外部无法改变,属于该函数不可改变的私有变量 新函数的实参

对象属性改变 外部无法改变,属于该函数不可改变的私有变量 新函数的实参

call也是函数原型对象上的一个方法,用于暂时改变函数的this指向

会对this指向的对象进行属性的读取,添加,修改,方法的调用

function showName() {
    this.id = 2;
    this.func_attr = "func_attr";
    console.log(this.id + ':' + this.name);
};

var obj = {
    id: 1,
    name: 'yuguang'
};


showName.call(obj);//=>2:yuguang
console.log(obj);//=>{id: 2, name: 'yuguang', func_attr: 'func_attr'}

call的基本思想,就是将函数暂时绑定到目标对象,然后在目标对象的作用域下执行函数;在函数执行时,函数可以通过this来对对象进行操作。之后,将函数从对象上移除。

    Function.prototype.newCall = function(obj) {
        obj.new_func = this; //调用newcall的对象是函数foo,this指向函数。现在使obj上有了一个新方法foo
        let args = [];
        for(let i = 1; i < arguments.length; i++ )
            args.push(arguments[i])
        let result = obj.new_func(...args);
        delete obj.new_func
        return result;

        
    }
    function foo(x, y) {
        this.name = x;
        this.attr = y;
        return y;
    }
    let obj = {
        name: "obj_name"
    }
    console.log(foo.newCall(obj, "first", "second")) //=> second
    console.log(obj); //=> {name: 'first', attr: 'second'}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红叶落水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值