07-call、 apply和 bind的使用

call、 apply和 bind的使用

一、用途

call()、apply()、bind() 都是用来重定义 this 这个对象的,

二、区别

call:改变了this指向 并 让函数执行,传递参数一个个传递
apply:改变了this指向 并 让函数执行,传送参数必须是数组
bind:改变了this指向 函数不执行。

三、使用

1.数据类型的检测

typof的不足:检测基本数据类型OK,对于引用数据类型来说,检测function也可以检测到,但是其它的检测的比较笼统,不够准确。

<script>
    console.log(typeof 1)     // number  ok
    console.log(typeof "hello") // string  ok
    console.log(typeof true)  // boolean  ok
    var a;
    console.log(typeof a)  // undefined  ok
    console.log(typeof [1,2,3])  // object  ok
    console.log(typeof {a:1})  // object  ok
    let d = new Date();
    console.log(typeof d)  // object  ok
    let r = new RegExp()    //正则
    console.log(typeof r)  // object  ok
    function f(){}
    console.log(typeof f)  // function  ok
</script>

利用Object.prototype.toString.call可以非常精确地检测一个数据的数据类型。思路:一个对象在调用toSring时,如果它的原型上有toString方法,就调用它的原型上的toString。没有的话,和会找Object的原型对象上的方法。这里直接去调用Object上面的toString方法,返回数据类型。

<script>
    // call  1)改变toString中的this的指向   指向了{}
    //       2)让toString执行

    console.log(Object.prototype.toString.call(1)); // 此时会把1瞬间包装成对象
    console.log(Object.prototype.toString.call("hello")); // 此时"hello"也瞬间包装成对象了
    console.log(Object.prototype.toString.call(true))
    var a;
    console.log(Object.prototype.toString.call(a))  
    console.log(Object.prototype.toString.call({}))
    console.log(Object.prototype.toString.call([]))
    function f(){}
    console.log(Object.prototype.toString.call(f))
    let d = new Date()
    console.log(Object.prototype.toString.call(d))
    let r = new RegExp();
    console.log(Object.prototype.toString.call(r))
</script>
一般对象通过打点调用
2.简单封装类进行数据类型检测
<script>
    function getType(abc) {
        var rs = Object.prototype.toString.call(abc);
        
        rs = rs.substr(8)       //截取字符串,具体使用在下面
        var len = rs.length

        return rs.substr(0,len-1).toLowerCase()     //转化为小写

    }

    console.log(getType(123));
    console.log(getType([]));
    console.log(getType({}));
    console.log(getType(new Date));
    console.log(getType(new RegExp));
    var f = function(){}
    console.log(getType(f));
</script>

1)substr()

转自:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/substr

substr() 方法返回一个字符串中从指定位置开始到指定字符数的字符。

语法
str.substr(start[, length])
参数
start:开始提取字符的位置。如果为负值,则被看作 strLength + start,其中 strLength 为字符串的长度(例如,如果 start 为 -3,则被看作 strLength + (-3))。

length:可选。提取的字符数。 
示例
    var str = "abcdefghij";

    console.log("(1,2): "    + str.substr(1,2));   // (1,2): bc
    console.log("(-3,2): "   + str.substr(-3,2));  // (-3,2): hi
    console.log("(-3): "     + str.substr(-3));    // (-3): hij
    console.log("(1): "      + str.substr(1));     // (1): bcdefghij
    console.log("(-20, 2): " + str.substr(-20,2)); // (-20, 2): ab
    console.log("(20, 2): "  + str.substr(20,2));  // (20, 2):
3.字符串进行翻转

方法一

<script>
    var str = "123456789";
    // 把上面的字符串进行翻转
    var newStr = "";
    // ...
    for (var i=str.length-1; i>=0; i&#45;&#45;){
        newStr += str[i];
    }
    console.log(newStr); // 987654321
</script>

方法二:

<script>
    // 数组中有一个翻转的方法
    var arr = [1,2,3];
    console.log(arr.reverse()); // [3, 2, 1]

    // 目标:让字符串翻转
    // 把字符串变成数组
    var str = "123456789";
    console.log(str.split(""));      // split()分割字符串 ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
    console.log(str.split("").reverse());           // ["9", "8", "7", "6", "5", "4", "3", "2", "1"]
    console.log(str.split("").reverse().join());    // 9,8,7,6,5,4,3,2,1
    console.log(str.split("").reverse().join(""));  // 987654321
</script>

1)join()

转自:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/join

join() 方法返回一个字符串中从指定位置开始到指定字符数的字符。

语法
arr.join([separator])
参数
separator(可选):指定一个字符串来分隔数组的每个元素。如果需要,将分隔符转换为字符串。如果缺省该值,数组元素用逗号(,)分隔。如果separator是空字符串(""),则所有元素之间都没有任何字符。
返回值
一个所有数组元素连接的字符串。如果 arr.length 为0,则返回空字符串。
示例
    var a = ['Wind', 'Rain', 'Fire'];
    var myVar1 = a.join();      // myVar1的值变为"Wind,Rain,Fire"
    var myVar2 = a.join(', ');  // myVar2的值变为"Wind, Rain, Fire"
    var myVar3 = a.join(' + '); // myVar3的值变为"Wind + Rain + Fire"
    var myVar4 = a.join('');    // myVar4的值变为"WindRainFire"
4.伪数组变成一个真实的数组

伪数组:长的像数组,但不是真正的数组,本质是对象,没有数组原型对象上的方法。

常见的伪数组
   1)通过document.getElementsByTagName获取的元素集合就是伪数组
   2)函数内部的arguments

arguemnts是函数内部的一个对象,用来收集实参,函数外部是不能访问arguments的

方法一:

    <span>1</span><span>2</span><span>3</span>

<script>
    // 如何把一个伪数组(对象)转成真实的数组
    var spans = document.getElementsByTagName("span");
    var arr = [];
    // 把一个伪数组变成一个真实的数组
    for (let i = 0; i < spans.length; i++) {
        arr.push(spans[i]);
    }
    console.log(arr);
</script>

方法二:

<span>1</span><span>2</span><span>3</span>

<script>
    var spans = document.getElementsByTagName("span");
    console.log(Array.isArray(spans));  // false

    // spans本质还是对象  让span借用slice方向
    console.log(Array.prototype.slice.call(spans));
    console.log(Array.isArray(Array.prototype.slice.call(spans)));  // true
</script>

1)slice()

转自:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/slice

substr() 方法返回一个字符串中从指定位置开始到指定字符数的字符。

语法
str.slice(beginIndex[, endIndex])
参数
beginIndex:从该索引(以 0 为基数)处开始提取原字符串中的字符。如果值为负数,会被当做 strLength + beginIndex 看待,这里的strLength 是字符串的长度(例如, 如果 beginIndex 是 -3 则看作是:strLength - 3)
endIndex:可选。在该索引(以 0 为基数)处结束提取字符串。如果省略该参数,slice() 会一直提取到字符串末尾。如果该参数为负数,则被看作是 strLength + endIndex,这里的 strLength 就是字符串的长度(例如,如果 endIndex 是 -3,则是, strLength - 3)。  
返回值
返回一个从原字符串中提取出来的新字符串
示例
    var str1 = 'The morning is upon us.', // str1 的长度 length 是 23。
    str2 = str1.slice(1, 8),
    str3 = str1.slice(4, -2),
    str4 = str1.slice(12),
    str5 = str1.slice(30);
    console.log(str2); // 输出:he morn
    console.log(str3); // 输出:morning is upon u
    console.log(str4); // 输出:is upon us.
    console.log(str5); // 输出:""

5.区别

call()方法

<script>
    function F(a,b) {
        return a+b;
    }
    var obj = {};
    F.call(obj); // 让F执行,关键是我们如何给F传递参数
    F(1,2); // 我们自己调用F函数  并  传递参数
    console.log(F.call(obj,4,5)); // call方法里面可以有多个参数
    // 第个参数表示谁去借用这个方法   后面的参数都是给这个方法传递的参数
</script>

apply()方法

<script>
    // apply  和  call一模一样  唯一区别是传递参数的区别
    function F(a,b) {
        console.log("F...")
        return a+b;
    }
    var obj = {};
    console.log(F.apply(obj,[1,2])); // 让obj借用F函数
</script>

bind()方法

<script>
    // bind  绑定的意思
    // call 改变了this指向 并 让函数执行   传递参数一个个传递
    // apply 改变了this指向 并 让函数执行   传送参数必须是数组
    // bind  改变了this指向 函数不执行
    function F(a,b) {
        console.log("F...")
        return a+b;
    }
    var obj = {};
    let k = F.bind(obj)
    console.log(k(1, 2));;
</script>

小练习

问:什么情况下,让a可以等于1,也可以等于2,也可以等于3
方法一:

<script>
    let a = {
        n:0, // a对象的私有属性  1
        toString:function () {  // a对象有私有属性(方法)
            // console.log("这是自己的toSring...")
            // this  ==>  a     this.n      a.n
            return ++this.n;
        }
    }
    // 显示地调用  a.toString()
    console.log(a == 1)
    console.log(a == 2)
    console.log(a == 3)
</script>

方法二:

<script>
    let a = {
        n:0,
        toString:function () {
            return ++this.n;
        }
    }
    if(a==1 && a==2 && a==3){
        console.log("ok");
    }
</script>

方法三:

<script>
    let a = [1,2,3];
    // ....   shift
    a.toString = a.shift; // 你调用toString就相当于调用了shift
    // a==1  先调用a.toString  内部调用了
    if(a==1 && a==2 && a==3){
        console.log("ok");
    }
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值