当前位置: 移动技术网 > IT编程>网页制作>CSS > 浅谈callapplybind

浅谈callapplybind

2018年11月29日  | 移动技术网IT编程  | 我要评论
浅谈call apply bind call方法 第一个参数是要绑定给this的值,第二部分参数要一个一个传。(当第一个参数为nll,nudefined的时候,默认指向window) 这是一个简单的

浅谈call apply bind

call方法

第一个参数是要绑定给this的值,第二部分参数要一个一个传。(当第一个参数为nll,nudefined的时候,默认指向window)

这是一个简单的例子:

//例1
var obj = {
    message: 'this is a people: '
}

function person(name, age) {
    console.log(this.message + name + ' ' + age)  //this is a people: xiaoming 18
}

person.call(obj, 'xiaoming', 18)

了解了它的基本语法后,我们来看这样一段代码:

//例2
    function a(a,b) {
        this.a = a;
        this.b = b;
    }
    function b() {
        this.a = 5;
        this.c = 3;
        a.call(this,1,2);
    }
    var s = new b();
    console.log(s.a+","+s.b+","+s.c);
输出是什么,是5,2,3 还是 1,2,3?
答案是后者,这是因为给b调用了a的call方法,使a的this指针指向了b,虽然我们在前面定义了b的a为5,但是在调用call方法之后又将b的a重写为了1。

上面两个都懂了 看一下第三个例子:

//例3
function a(){
        this.show = function(){alert(this.name)}
    }
    function b(){
        this.name = 'b';
    }
    var c = new a();
    var d = new b();
    c.show.call(d);//b
    alert(d.show);//undefined
    
//这段代码中,让c.show中的this指向了d,改变了匿名函数里面的this.name的值
//但是并没有给d写入c.show,所以第一个输出b第二个输出undefined

apply

接受两个参数,第一个参数是要绑定给this的值,所有参数都必须放在一个数组里面作为第二个参数传进去。(当第一个参数为null、undefined的时候,默认指向window。)

call 和apply是立即调用

bind

类似于call,第一个参数是this的指向,从第二个参数开始是接收的参数列表。(区别在于bind方法返回值是函数以及bind接收的参数列表。)

var obj = {
    name: 'xiaoming'
}

function person() {
    console.log(this.name)
}

var people = person.bind(obj)  
console.log(people)  // person() {...}
people()             //xiaoming

bind是新创建一个函数,然后把它的上下文绑定到bind()括号中的参数上,然后将它返回。所以,bind后函数不会执行,而只是返回一个改变了上下文的函数副本。(一般需要一般变量来接受它的返回值) 而原函数 printname 中的 this 并没有被改变,依旧指向全局对象 window。
bind中参数的使用:

来,我们再来看一个好玩的东西:

function fn(a, b, c) {
    console.log(a, b, c);
}
var fn1 = fn.bind(null, 'xiaoming'); //相当于已将fn1中第一个参数的值确定好了

fn('a', 'b', 'c');            // a b c
fn1('a', 'b', 'c');           // dot a b  //传入的实参依次向后对应一位
fn1('b', 'c');                // dot b c
fn.call(null, 'xiaoming');    // dot undefined undefined

对call 来说它会严格遵照将第二个及其以后的参数作为实参传入fn,而对于bind方法 fn1的实参是在bind中已确定值的参数 基础上向后排的。

三者的使用区别

都是用来改变函数的this对象的指向的;(第一个参数都是this要指向的对象)
2.都可以利用后续参数传参; bind是返回对应函数,便于稍后调用,apply、call是立即调用;

看了这么多,你或许还回小瞧它们,难道应用它们仅仅是为了改变this指向,哈哈,当然不是了!

有何用处?

1. 将类数组转化为数组

将这个之前我们先来简单回答一下类数组和数组的关系:类数组(1)拥有length属性 (2)不具有数组所具有的方法

常见的类数组有哪些呢?
参数的参数 arguments,dom 对象列表(比如通过 document.getelementsbytags 得到的列表),jquery 对象(比如 $(“p”))

原生js中的方法:
var arr = array.prototype.slice.call(类数组);

该方法等价于:
var arr = [].slice.call(类数组);

刚看到设个方法的时候,自己很是疑惑,为啥这样就可以。再网上看到一篇文章博主是这样解释的,觉得很有道理:

array.prototype.slice.call(arguments);

它会将一个类数组形式的变量转化为真正的数组。为啥呢,其实书上并没有说slice还有这样的用法,也不知道是谁发明的。slice的用法可以顺便上网查一下,就能查到。但要更正一点,网上的介绍说slice有两个参数,第一个参数不能省略。然而我不知道是我理解的问题还是咋地,上面这段代码不就是典型的没传参数吗!!!arguments是传给call的那个上下文,前面讲过,不要弄混(由于arguments自己没有slice方法,这里属于借用array原型的slice方法)。而且经过测试,若果你不给slice传参数,那就等于传了个0给它,结果就是返回一个和原来数组一模一样的副本。这之后的代码就很好理解,返回一个函数,该函数把传给bind的第一个参数当做执行上下文,由于args已经是一个数组,排除第一项,将之后的部分作为第二部分参数传给apply。

2. 数组追加(当然这里可以用数组的拼接函数concat)

var arr1 = [1,2,3];
var arr2 = [4,5,6];
var total = [].push.apply(arr1, arr2);//6
// arr1 [1, 2, 3, 4, 5, 6]
// arr2 [4,5,6]

在这里增加一个知识:
push 添加只能将添加项作为一个子元素,增加到母数组的后面

var arr1=[1,2,3,4];
    var arr2=[5,6,7,8];
    
    arr1.push(arr2);
    console.log(arr1); //(5) [1, 2, 3, 4, array(4)]

3.利用call apply做继承

function person(name,age){
    // 这里的this都指向实例
    this.name = name
    this.age = age
    this.sayage = function(){
        console.log(this.age)
    }
}
function boy(){
    person.apply(this,arguments)//将父元素所有方法在这里执行一遍就继承了
}
var dcbryant = new boy('dcbryant',22)

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网