美文网首页
JavaScript call apply bind 学习笔记

JavaScript call apply bind 学习笔记

作者: 愤的小鸟怒 | 来源:发表于2019-07-25 13:40 被阅读0次

在JavaScript里使用typeof判断数据类型,只能区分基本类型,即:number、string、undefined、boolean、object。对于null、array、function、object来说,使用typeof都会统一返回object字符串。

对于这个问题,我们可以使用 Object.prototype.toString.call() 的方法解决。

Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(“abc”);// "[object String]"
Object.prototype.toString.call(123);// "[object Number]"
Object.prototype.toString.call(true);// "[object Boolean]"

1. call()

语法:

fun.call(thisArg[, arg1[, arg2[, ...]]])

thisArg:fun函数运行时指定的this值,可能的值为:

  1. 不传,或者传null,undefined, this指向window对象
  2. 传递另一个函数的函数名fun2,this指向函数fun2的引用
  3. 值为原始值(数字,字符串,布尔值),this会指向该原始值的自动包装对象,如 String、Number、Boolean
  4. 传递一个对象,函数中的this指向这个对象

call()、 apply()、 bind() 的区别:

call()、 apply() 基本一样,只是 apply 参数接受一个数组,而 call 接受若干个参数。bind()函数实际上是新建一个函数,不会立即执行,需要调用才能执行。

创建一个对象的时候,new 都做了什么事情:

var a = new myFunction("Li","Cherry");

new myFunction{
    var obj = {};
    obj.__proto__ = myFunction.prototype;
    var result = myFunction.call(obj,"Li","Cherry");
    return typeof result === 'obj'? result : obj;
}

从上述过程可以看出来:

  1. 创建一个空对象 obj;
  2. 将新创建的空对象的隐式原型指向其构造函数的显示原型。
  3. 使用 call 改变 this 的指向
  4. 如果无返回值或者返回一个非对象值,则将 obj 返回作为新对象;如果返回值是一个新对象的话那么直接直接返回该对象。

----------------------------------------- call apply bind 常用的应用场景 -------------------------------

call apply bind 常用的应用场景

(一) 求数组中的最大和最小值

var arr = [34,5,3,6,54,6,-67,5,7,6,-8,687];
Math.max.apply(Math, arr);
Math.max.call(Math, 34,5,3,6,54,6,-67,5,7,6,-8,687);
Math.min.apply(Math, arr);
Math.min.call(Math, 34,5,3,6,54,6,-67,5,7,6,-8,687);

(二) 将伪数组转化为数组

什么是伪数组?
1. js 的伪数组是一个包含 length 属性的 json 对象,length 是必备的。
2. 它是按照索引的方式存储数据的。
3. 它不具备数组拥有的方法,只能通过 call 或者 apply 转化为数组后才能使用。

例如:

    var obj = {0:'a',1:'b',length:2}; // 伪数组
    var arr = Array.prototype.slice.call(obj); // 转化为数组    
    console.log(arr);  // 返回["a","b"]

如何将伪数组转化伪数组?

  1. [].slice.call()这种形式实现同样的效果
  2. Array.prototype.slice.call()

为什么可以将伪数组转化伪数组,下面是 Array 对象的 slice 方法的实现过程?

function slice(obj) {
    var arr =[];
    var len = obj.length; // length 正好对应伪数组中的length属性
    for(var i = 0;i < len;i++){
        arr.push[i] = obj[i]; // i 正好对应伪数组中的索引值
    }
    return arr;
}

这个过程显示了一个伪数组对象 obj 经过一系列操作变成 arr 返回,因此可以看出,对于一个伪数组对象,length 是必须的,且伪数组的键必须是 0,1,2...length - 1 这种方式排列的。

常见伪数组有:

  1. 函数的参数 arguments 对象。
  2. getElementsByTagName 等方法。
  3. document.childNodes 方法。

(三) 数组的 push 方法

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

(四) 判断数据类型
对于对象型的数据类型,我们可以借助call来得知他的具体类型,例如数组

function isArray(obj){
  return Object.prototype.toString.call(obj) == '[object Array]';
}
isArray([]) // true
isArray('qianlong') // false

(五) 利用call和apply做继承

var Person = function (name, age) {
  this.name = name;
  this.age = age;
};
var Girl = function (name) {
  Person.call(this, name);
};
var Boy = function (name, age) {
  Person.apply(this, arguments);
}
var g1 = new Girl ('qing');
var b1 = new Boy('qianlong', 100);

相关文章

网友评论

      本文标题:JavaScript call apply bind 学习笔记

      本文链接:https://www.haomeiwen.com/subject/ytncrctx.html