上下文调用模式

可以修改this的值,也就是可以修改函数的调用方式,apply、call可以修改函数调用上下文,也就是this的值

<script>
var name = "莱昂纳多·自强·郭"; function sayHello(a, b) {
console.log(this.name + "吃了" + (a * b) + "个馒头");
} var obj = {
name: "尼古拉斯·电饭·锅"
} var arr = [10, 20];
sayHello.apply(obj, arr);//尼古拉斯·电饭·锅吃了200个馒头
sayHello.call(obj, 2, 3);//尼古拉斯·电饭·锅吃了6个馒头
</script>

apply与call的区别

函数.apply(对象, [函数需要参数列表,是一个数组])

函数.call(对象,arg1,arg2,arg3...argn)

具体区别就是apply参数是一个数组,而call传入函数的参数是一个值一个值的方式,所以根据他们的特性,运用情况也是不同:

1、apply用于函数的形参个数不确定的情况

2、call用于确定了函数的形参有多少个的时候使用

apply与call应用于伪数组的场景

(1)伪数组其实不是数组,并没有数组中的方法,但是表现形式却又很像数组

<script>
var obj = {
0: 2,
1: 3,
2: 9,
3: 20.
length: 4
}
</script>

上面其实是一个对象,但是如果拿obj.0来访问属性0对应的值是访问不了的,但是像数组一样访问obj['0']确实可以的,DOM里面的div元素的集合其实也是一个伪数组

(2)利用apply与call可以轻易借用数组的方法操作伪数组

<script>
var obj = {
0: 2,
1: 3,
2: 9,
3: 20,
length: 4
}
Array.prototype.push.call(obj, 100);
console.log(obj);//{0: 2, 1: 3, 2: 9, 3: 20, 4: 100, length: 5}
Array.prototype.splice.call(obj, 1, 1);
console.log(obj);//{0: 2, 1: 9, 2: 20, 3: 100, length: 4}
</script>

(只有这样才会正常显示)

当我们声明一个数组arr,arr有join()方法,执行的过程是遍历arr中的数据;arr对象的join方法其实是Array构造函数原型的方法,所有我们可以借用Array.prototype.join(),传递的第一个参数,是伪数组,上面提过join方法的执行过程的this就是遍历调用的对象arr,所以现在传递伪数组,改变了this,也会将伪数组遍历一遍

案例分析

(1)求一个数组的最大值

<script>
var arr = [9, 1, 4, 10, 7, 22, 8];
//apply方法的第二个参数 是一个数组
// 在调用的时候,会将数组中的每一个元素拿出来,作为形参,挨个传递给函数
//apply方法和call方法第一个参数传递null的时候,都表示为函数调用模式
//也就是将this指向window
var max = Math.max.apply(null, arr);
//==>等同于Math.max(9,1,4,10,7,22,8)
console.log(max);//22
</script>

(2)将传入的参数打印,并且用’-‘连接

<script>
function foo() {
//伪数组不具有join方法,所以这个时候就要考虑去借用一下数组的join方法
//var str = Array.prototype.join.apply(arguments,["-"]);
var str = [].join.apply(arguments, ["-"]);
return str;
} var str = foo(1, 3, "abc", "ffff", 99) // 1-3-abc-ffff-99
console.log(str);
</script>

(3)设置div、p标签的颜色

<script>
var divs = document.getElementsByTagName('div');
var ps = document.getElementsByTagName('p');
var arr = [];
arr.push.apply(arr, divs);
arr.push.apply(arr, ps);
for (var i = 0; i < arr.length; i++) {
arr[i].style.backgroundColor = 'yellow';
}
</script>

(4)打印简单类型真正的类型

自定义类型的tostring方法最后输出的都是【object object】,但是简单类型输出的确实具体数值,那么,简单类型肯定重写了object的tostring方法,如果才能向自定义类型那样看到最后的类型

<script>
var a = [1, 2];
console.log(a.toString());//1,2
var obj = {
name: 'qx'
};
console.log(obj.toString());//[object Object]
console.log(Object.prototype.toString.call(a));//[object Array]
</script>

(5)

<script>
function test() {
console.log(this);//Number {1}
console.log(this.valueOf());
console.log(+this);
console.log("" + this);
} test.apply(1);
test.apply("abc");
test.apply(true)
test.apply(undefined) //当时用call和apply传入的第一个参数为值类型的时候
//会将值类型转换成对应的对象(引用类型) 然后赋值给this //当传入的第一个参数为 null或者Undefined的时候,
//会把this赋值为 window
</script>

(6)借用构造函数实现继承

<script>
//借用构造函数 实现继承
function Person() {
this.name = "张莎";
this.age = 18;
} function Student() {
var stu = this;
Person.apply(stu);
} var stu = new Student();
console.log(stu);
</script>

JS高级——apply与call的更多相关文章

  1. Ext.js高级组件

    第二章:Ext.js高级组件 grid组件 普通方式 表格面板类Ext.grid.Panel xtype(别名):gridpanel.grid title标题.renderTo渲染至.width宽.h ...

  2. JS高级(摘自简书)

    JS高级 1. 访问对象属性(方法也是属性)的通用方式:obj['属性名'] 1. 属性名包含特殊字符,如"-".空格,访问:obj['content-type'] 2. 属性名不 ...

  3. JS高级前端开发群加群说明及如何晋级

    JS高级前端开发群加群说明 一.文章背景: 二. 高级群: 三. 加入方式: 四. 说明:   一.文章背景: 去年年初建了几个群,在不经意间火了,一直排在“前端开发”关键字搜索结果第一名.当然取得这 ...

  4. 前端进阶试题css(来自js高级前端开发---豪情)既然被发现了HOHO,那我就置顶了嘿嘿!觉得自己技术OK的可以把这套题目做完哦,然后加入高级前端的社区咯

    http://www.cnblogs.com/jikey/p/4426105.html js高级前端开发加群方法(此群很难进,里面纯技术,严禁广告,水群) 完整题目做完发邮箱(jikeytang@16 ...

  5. js高级应用

    特别板块:js跨域请求Tomcat6.tomcat7 跨域设置(包含html5 的CORS) 需要下载两个jar文件,cors-filter-1.7.jar,Java-property-utils-1 ...

  6. 原生JS中apply()方法的一个值得注意的用法

    今天在学习vue.js的render时,遇到需要重复构造多个同类型对象的问题,在这里发现原生JS中apply()方法的一个特殊的用法: var ary = Array.apply(null, { &q ...

  7. js中apply方法的使用

    js中apply方法的使用   1.对象的继承,一般的做法是复制:Object.extend prototype.js的实现方式是: Object.extend = function(destinat ...

  8. Node.js高级编程读书笔记Outline

    Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...

  9. 读JS高级——第五章-引用类型 _记录

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. 放大的X

    Problem Description 请你编程画一个放大的’X’.如3*3的’X’应如下所示: X X XX X 5*5的’X’如下所示:X X X X X X XX X   Input 输入数据第 ...

  2. [bzoj 1093][ZJOI2007]最大半联通子图(强联通缩点+DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1093 分析: 首先肯定是先把强联通全部缩成一个点,然后成了一个DAG 下面要知道一点: ...

  3. W3School Redis教程(安装/基本操作/高级操作/命令/官方文档/官方集群教程)

    说明:Redis有自身的客户端连接软件,也可以使用Telnet进行连接操作. 来自W3School的Redis教程,基本上涵盖了从安装到状态监控的教程. W3School:https://www.gi ...

  4. webservice Connection timed out

    webservice Connection timed out,当发生webservice的链接超时错误时.我想原因无非就是webclient到webservice之间的链接通路发生了异常,那么该怎样 ...

  5. Unicode不可见字符的显示

    Unicode的学名是”Universal Multiple-Octet Coded Character Set”,简称为UCS 不可见字符”/u200b”为 Unicode Character ‘Z ...

  6. android自己定义之 5.0 风格progressBar

    近期做项目,用到了ProgressBar .就想到了要使用Android5.0 的效果,就随手实现了一下. 效果图: 大概的思路: 1. 圆圈通过Canvas去绘制 2.圆圈的动画通过Animator ...

  7. 微信前端js sdk以外的开发

    此时页面中就会出现刚才我画红圈部分的工具条. 这个工具条再加上上面的标题栏工具条. 极大的降低了可视区域的面积. 是否能将它去掉呢?答案是能够的.增加以下代码就能够去掉微信中以下的工具条: docum ...

  8. JavaSE入门学习10:Java修饰符

    Java语言提供了非常多修饰符,主要分为下面两类: 訪问修饰符 非訪问修饰符 修饰符用来定义类.方法或者变量.通常放在语句的最前端.我们通过以下的样例来说明: <span style=" ...

  9. 四:Java之字符串操作String、StringBuffer和StringBuilder

    string是我们经经常使用到的一个类型,事实上有时候认为敲代码就是在重复的操作字符串,这是C的特点,在java中.jdk非常好的封装了关于字符串的操作.三个类String .StringBuffer ...

  10. ES 2016+

    ES2016(ES7)新增: Array.prototype.includes Exponentiation Operator 求冥运算 ES2017 (ES8)新增: ECMAScript® 201 ...