javascript 设计模式 学习笔记(二)--基础(call,apply)

1.call和apply的区别
他们的作用一模一样,区别在于传入参数的形式不同

apply 接受两个参数,第一个参数指定了函数体内的this对象的指向,第二个参数为一个带下标的集合,可以为数组,也可以为类数组,apply方法把这个集合中的元素作为参数传递给被调用的函数

var func=function(a,b,c){
    alert([a,b,c]);
};
func.apply(null,[1,2,3]);//输出[1,2,3]

call传入的参数是不固定的,跟apply相同的是,第一个参数也是代表函数体内的this的指向,从第二个参数开始往后,没个参数被依次传入函数

var func=function(a,b,c){
    alert([a,b,c]);
};
console.log(null,1,2,3);//输出[1,2,3]

在使用call或者apply的时候,如果第一个参数为null,函数体内的this会指向默认的宿主对象,在浏览器中则为window.

2.call和apply的用途

改变this指向

var obj1={name:''seven};
var obj2={name:'anne'};
window.name='window';
var getNmae=function(){
    alert(this.name);
};
getName();//输出:window
getName.call(obj1);//输出:seven
getName.call(obj2);//输出:anne

使用call来修正this的场景

document.getElementById=(function(func){
    return function(){
        return func.apply(document,arguments);
    }
})(document.getElementById);
var getId=document.getElementById;
var div=getId('div1');
alert(div.id);//输出div1

Function.prototype.bind

大部分高级浏览器都实现了内置Function.prototype.bind,用来指定函数内部的this指向,即使没有原生的Function.prototype.bind实现,也能模拟一个,如下:

Function.prototype.bind=function(context){
    var self=this;
    return function(){
        return self.apply(context,arguments);//执行新函数时,会把之前传入的context当作新函数体的this
    }
};
var obj={neme:'seven'};
var func=function(){
    alert(this.name);
}.bind(obj);
func();//输出:seven

传参数的bind函数实现

Function.prototype.bind=functiom(){
    var self=this,
        context=[].shift.call(arguments),
        args=[].slice.call(arguments);
    return function(){
        return self.apply(context,[].concat.call(args,[],slice.call(arguments)));
        //执行新函数时,会把之前传入的context当作新函数体的this

        //并且组合两次分别传入的参数,作为新函数的参数
    }
};
var obj={name:'seven'};
var func=function(a,b,c,d){
    alert(this.name);
    alert([a,b,c,d]);
}.bind(obj,1,2);
func(3,4);//输出:seven      [1,2,3,4]

借用其它对象的方法
第一种借用场景:借用构造函数,通过此种方法,可以实现一些类似继承的效果

var A=function(name){
    this.name=name;
};
var B=function(){
    A.apply(this,arguments);
};

B.prototype.getName=function(){
    return this.name;
};
var b=new B('seven');
console.log(b.getName());//输出:seven

借用的第二种场景:函数的参数列表是一个类数组对象,虽然也有下标,但并非真正的数组,所以不能像数组一样进行排序,插入,这是我们会借用Array.prototype对象上的方法,比如向arguments中添加一个新元素。

(function(){
    Array.prototype.push.call(arguments,3);
    console.log(arguments);//输出:1,2,3]
})(1,2;)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值