• apply和call和bind


     call和apply是定义在Function.prototype上的方法.

    共同点:可以自由指定函数执行时内部this的指向

    不同点:传参方式不同

    call方法: 
    语法:call(thisObj,Object)
    定义:调用一个对象的一个方法,以另一个对象替换当前对象。
    说明:
    call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。 
    如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。 

    apply方法: 
    语法:apply(thisObj,[argArray])
    定义:应用某一对象的一个方法,用另一个对象替换当前对象。 
    说明: 
    如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。 
    如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

    /*
    * 在IE以及以前,apply方法只能平铺真数组,或者内置的伪数组,
    * 用户自定义的伪数组不认,会报错。
    * */

    var likeArray = { 0: 'abc', 1: 'cbs', length: 2 };
    var obj = {};

    [].push.apply( obj, [].slice.call( likeArray ) );


    /*
    * slice:
    * 截取数组指定位置的数据,组成新的数组返回
    * */

    var arr = [ 1, 2, 3, 4, 5, 6 ];
    console.log(arr.slice(1, 3));
    console.log(arr);

    // 可以借用数组的slice方法,通过伪数组得到真数组
    console.log(arr.slice.call( likeArray ));

     // IE8中apply不能平铺用户自定义的伪数组

     // [].push.apply( target, [].slice.call( obj2 ) ); // 使用slice方法把用户自定义的伪数组转换为真数组

    // 浏览器创建的DOM相关的伪数组对象
    var nodes1 = document.querySelectorAll('title');
    var nodes2 = document.getElementsByTagName('body');

    //但是ie8却不能使用slice操作除了ECMA外的对象(比如说var obj={0:1,1:2,length:2}就是ECMA对象,而var obj1=document.querySelectorAll('title');和var obj2=document.getElementsByTagName('body');都是通过document获取的伪数组就不能用slice转换为真数组)
    console.log([].slice.call(obj2));
    console.log([].slice.call(nodes1)); // nodes1是DOM方法返回的伪数组,IE8报错

    /*
    * bind:
    * ES5新增的方法,IE9及以上支持。
    * bind和call、apply一样,可以自由执行函数执行时内部的this,
    * 不同之处在于,call和apply会马上执行函数,
    * 而bind会返回函数的copy版本,什么时候执行,由用户根据情况而定。
    * */

    // bind接收绑定了this的函数clone版本,
    // 这个版本接收后可以多次调用。但是call和apply指定的函数只可以执行一次,想要多次执行函数,就得多次调用call和apply
    var fnClone = fn.bind( ['abc', 'cbs'] );
    fnClone();
    fnClone();


    // bind方法不光可以绑定this,还可以绑定参数
    function add3( a, b, c ) {
    console.log( a + b + c );
    }
    var add3Clone = add3.bind( null, 10, 20 );
    add3Clone( 30 );

    //顺便记录一下concat方法:

    var arr=[1,2,3];

    var arr2=[4,5,6];

    var obj={0;1,1:2,2,:3,length:3};

    //对于真数组,concat会把每一项合并到target中,

    console.log(arr.concat(arr2));//==>[1,2,3,4,5,6]

    //但是对于伪数组,concat会把伪数组整体合并到arr中

    console.log(arr.concat(obj));//==>[1,2,3,{{0;1,1:2,2,:3,length:3}}]

    //要想合并伪数组,只能借用slice将伪数组转换为真数组,再用apply方法将数组平铺到arr中

    console.log(arr.concat([].slice.apply({0;1,1:2,2,:3,length:3})));//==>[1,2,3,1,2,3]

  • 相关阅读:
    qt预览的UI界面和实际运行出来的界面分辨率不一样
    QByteArray转QString 例如 0x45 转成 “45”
    QML访问C++成员函数报错:TypeError: Property 'showHome' of object [object Object] is not a function
    Qt生成二维码
    Android解析编译之后的所有文件(so,dex,xml,arsc)格式
    Android逆向之旅---解析编译之后的Dex文件格式
    Android逆向之旅---解析编译之后的Resource.arsc文件格式
    Android逆向之旅---解析编译之后的AndroidManifest文件格式
    Android签名机制之---签名验证过程详解
    Android签名机制之---签名过程详解
  • 原文地址:https://www.cnblogs.com/luxiaoxiao/p/6101390.html
Copyright © 2020-2023  润新知