上下文调用模式

可以修改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. G - 免费馅饼 基础DP

    都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内.馅饼如果掉在了地上当然就 ...

  2. Oops, 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine error

    环境: Win7 64位 + VS2005 + Office2013 64位 现象:程序为一个Excel导入程序,导入时报「'Microsoft.ACE.OLEDB.12.0' provider is ...

  3. 一个样例看清楚JQuery子元素选择器children()和find()的差别

    近期在我们的hybrid app项目开发中定位出了一个问题.通过这个问题了解下JQuery选择器find()和children()的差别.问题是这种:我们的混合app是一个单页面应用(main.htm ...

  4. 【MVC框架】——View和Controller之间的传值

    在MVC中,Controller运行一个能够说是路由功能.它通过View传过来的数据,来决定应该调用哪一个Model,相同会把Model处理完的数据传给View,所以就总是涉及到Controller和 ...

  5. Powershell远程在Azure A7虚拟机执行Java JVM失败

    近期.使用Powershell脚本在A7 (8核,56G内存)配置的 Azure VM(Virtual Machine.虚拟机)上远程运行Java JVM时 (java.exe -version).总 ...

  6. LeetCode 929. Unique Email Addresses (独特的电子邮件地址)

    题目标签:String 题目说明 有两个规则针对于 local name. 所以先把local name 和 domain name 分开. 两个规则是: rule 1:'.' 会被去除. (利用re ...

  7. LeetCode总结--二分查找篇

    二分查找算法尽管简单,但面试中也比較常见.经经常使用来在有序的数列查找某个特定的位置.在LeetCode用到此算法的主要题目有: Search Insert Position Search for a ...

  8. CountDownTimer完整具体演示样例

    MainActivity例如以下: package cc.cv; import android.os.Bundle; import android.os.CountDownTimer; import ...

  9. 【bzoj1207】[HNOI2004]打鼹鼠

    看了数据范围,想想这不暴力可以过??   DP   #include<algorithm> #include<iostream> #include<cstdlib> ...

  10. shell curl 实现rest 并发测试

    for i in {1..50}; do curl http://10.43.95.26:5812/rdk/service/app/example/server/my_service & do ...