资讯专栏INFORMATION COLUMN

函数中的apply,call入门介绍

yankeys / 2157人阅读

摘要:函数中的入门牵扯到就要先说一下它们和函数的渊源函数既是也是对象它和其它的对象没有什么区别。但是我们可以通过和在函数调用时显示指定所需的值。那就意味这任何函数可以被任何对象调用这才是和的方法的最终目的。否则会出现数组元素为的情况值值值值值

函数中的apply,call入门

  牵扯到apply,call就要先说一下它们和函数的渊源

Javascript函数既是也是对象

  它和其它的javascript对象没有什么区别。并且每个函数都包含两个非继承而来的方法 apply()和call(),这两个方法都可以间接的调用函数

例如:

function f() {
    console.log(1);
}
f.call(); //1
f.apply(); //1

  并且这两个方法都允许显示的指定函数调用后的this值。
  关于this值,由于this值的是在进入执行上下文阶段被确认的,所以this的值让人琢磨不透。但是我们可以通过apply()和call() 在函数调用时显示指定所需的this值。

那么apply和call方法到底是用来做什么的呢?

  任何函数在调用时都可以被指定this值,作为this指向的对象的方法来调用。

那就意味这任何函数可以被任何对象调用,这才是apply和call的方法的最终目的。

  让我们来一个使用例子来理解

function Animal() {};
Animal.prototype = {
    constructor: Animal,
    other: function() {
        console.log("这是一只" + this.name);
    }
}
var animal = new Animal();
//定义一个对象
var dog = {
    name: "狗"
};

//我的dog对象想使用Animal函数的other方法怎么办,使用call或apply
animal.other.call(dog);
animal.other.apply(dog);

  在上面,我们将animal.other(思考一下它是什么,是的,它本质上也是一个函数)作为dog对象的方法调用。接下来,我们运用的实际一些.

//设置一个类数组对象
var arrLike = {
    0: "我是apply",
    1: "我是call",
    length: 2
}

//将Arrar的slice函数的this显式指向arrLike,并将0作为参数传入slice函数
var newArr = Array.prototype.slice.call(arrLike, 0);
//等价于 
arrLike.slice(0);
console.log(newArr);

  对于apply()和cal()所有传入它们的第一个实参都会变为this的值,哪怕传入的实参是原始值,null,undefined。而如果传入的第一个实参是undefined和null 在ES3和非严格模式下会被全局对象替换掉,而其它的原始值则会被相应的包装对象所替代

  用通俗一点的话来说,Js根本不在乎apply/call 的第一个参数是什么,函数仍然会被调用,只不过调用会不会报错是另一码事.

var str = "我是一个函数";
//将字符串传入,但是String对象无法调用slice属性 报错
Array.prototype.pop.call(str);

  为了能对这两个方法记忆深刻以及何时用这两个方法,列出一些常用的用法

  首先,就现在来说,这两种方法的性能差异几乎忽略不记,所以他们之间如何使用呢?

  apply()方法适用于传入第二个参数是有序且参数不定的就使用apply方法,比如函数的arguments这个类数组对象就很适合作为参数传递。

function A(a, b, c) {
    console.log(a, b, c);
}

var fn = (function(func, b, c) {
    var args = arguments;
    return () => {
        func.apply(null, args);
    }
}(A, 66, 99));

fn();

再比如说给数组追加元素

var arr1 = [1, 2, 3];
var arr2 = [66, 99, 131];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1);

同样将arr2数组作为参数传递。

而对于无序,相互之间没有什么关联的参数,就使用call()

获取数组的最大值和最小值

var arr = [0, 1, 2, 3, 4];

//获取最大数
var max1 = Math.max.apply(Math, arr),
    max2 = Math.max.call(Math, 0, 1, 2, 3, 4),

    //获取最小数
    min1 = Math.min.apply(Math, arr),
    min2 = Math.min.call(Math, 0, 1, 2, 3, 4);
console.log(max1, max2, min1, min2);

arr本身是没有Math方法的,但是我们可以用call或者apply使用其方法

判断对象的具体类型

//验证对象的具体类型
var arr = [];
var type = Object.prototype.toString.call(arr);
console.log(type);// [object Array]

在使用typeof时得到的结果都是Object,无法判断具体是哪一种类型。于是可以用 Object.prototype.toString.call()来获得具体类型。当然,前提是toSting()方法没有被重写过

将类数组对象转为真正的数组,通常我们使用Array.prototype.slice.call() 来转换

var arrLike = {
    length: 3,
    0: "值1",
    1: "值2",
    2: "值3"
}
var newArr = [].__proto__.slice.call(arrLike);
var type = Object.prototype.toString.call(newArr);
console.log(newArr, type); //[ "值1", "值2", "值3" ] "[object Array]"

当然,splice,concat也可以将类数组对象转数组.

这里普及一下类数组对象
通过索引访问元素,并且拥有length属性
也就是说,需要满足两个条件,1.使用序号定义属性,2.拥有length属性,属性值为元素个数
在使用序号定义属性时,建议从0开始按顺序定义属性。否则会出现数组元素为empty的情况

var arrLike = {
    length: 3,
    0: "值1",
    1: "值2",
    3: "值3"
}
var newArr = [].__proto__.slice.call(arrLike);
var type = Object.prototype.toString.call(newArr);
console.log(newArr, type); //[ "值1", "值2", empty] [object Array]

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/103139.html

相关文章

  • javasscript - 收藏集 - 掘金

    摘要:跨域请求详解从繁至简前端掘金什么是为什么要用是的一种使用模式,可用于解决主流浏览器的跨域数据访问的问题。异步编程入门道典型的面试题前端掘金在界中,开发人员的需求量一直居高不下。 jsonp 跨域请求详解——从繁至简 - 前端 - 掘金什么是jsonp?为什么要用jsonp?JSONP(JSON with Padding)是JSON的一种使用模式,可用于解决主流浏览器的跨域数据访问的问题...

    Rango 评论0 收藏0
  • D1.Nodejs 入门

    摘要:上下文切换上下文最直观的表现就是代码块中的,通常在面向对象的编程中用到,来指代当前类生成的对应实例,与其他语言的一致。咦,是干嘛的,有没有其他方式实现,请自行谷歌。 分享第一篇,关于 NodeJS —— Javascript 的常用知识以及如何从 Javascript 开发者过渡到 NodeJS 开发者(不会介绍具体的框架)。在读本文前,希望你对 javascript 有一些初步的认识...

    Rango 评论0 收藏0
  • 深入理解 React 中的上下文 this

    摘要:写在前面中的作用域和上下文是这门语言的独到之处,每个函数有不同的变量上下文和作用域。不可以当作构造函数,也就是说,不可以使用命令,否则会抛出一个错误。正是因为它没有,所以也就不能用作构造函数。 写在前面 JavaScript中的作用域scope 和上下文 context 是这门语言的独到之处,每个函数有不同的变量上下文和作用域。这些概念是JavaScript中一些强大的设计模式的后盾。...

    Magicer 评论0 收藏0
  • javascript this的学习总结

    摘要:例如通过,调用时强制把它的绑定到上。箭头函数问题箭头函数体内的对象就是定义时所在的对象,而不是使用时所在的对象,固定不变。 刚入门javascript,关于this的学习,花了自己挺多的时间,做了比较多的功课,看了一篇又一篇的文章,也看了一些书籍,今天就结合看的那些东西总结下自己所学到的东西,方便留着以后回看,进一步的学习,这篇文章会不断的更新,不断的更新自己的想法,现在还是一个入门不...

    A Loity 评论0 收藏0
  • JavaScript中对this深入了解

    摘要:但是有一个总的原则,那就是指的是调用函数的那个对象。作为构造函数调用如果在一个函数前面带上来调用,那么背地里将会创建一个链接到该函数的成员的新对象,同时会被绑定到那个新对象上。使用或调用方法让我们构建一个参数数组传递给调用函数。 让我们深入探索一下this的具体用法 只有了解this用法才算真正入门了 showImg(https://segmentfault.com/img/bVYh1...

    April 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<