上下文调用模式

可以修改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. hdu 1867 kmp匹配

    #include<stdio.h> #include<string.h> #define N 100100 void getnext(int next[],char s[]) ...

  2. JavaSE部分之(1)Java基础

    JavaSE部分之(1)Java基础 1.为什么重写equals还要重写hashcode 为了提高程序的效率才实现了hashcode方法,先进行hashcode的比较,如果不同,那就没必要再进行equ ...

  3. JAVA和C语言的区别

    java语言和c语言的区别:                                      1 un 公司推出的Java 是面向对象程序设计语言,其适用于Internet 应用的开发,称为 ...

  4. -- > define的用法与学习(1)

    在不久之前,我一直不理解为神马大家在做题时经常用define来代替某些函数,或者用来直接定义某些极大的变量.It is not until today that I understand why it ...

  5. 前段集成解决方案grunt+yeoman初步认识

    1.什么是前段集成解决方案? 将前端研发领域中各种分散的技术元素集中在一起,并对常见的前端开发问题.不足.缺陷和需求,所提出的一种解决问题的方案 2.yeoman 应用的架构,模型!  相当于一个生成 ...

  6. ArcGIS ArcMap “ Add Data” 打开后,一直卡死,无内容

    打开ArcMap能打开,Add Data 或打开mxd就出Runtime Error对话框.打开ArcCatlog或者ArcGlobe出现Runtime Error对话框Runtime Error!P ...

  7. POJ-3268-最短路(dijkstra算法)

    Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12494   Accepted: 5568 ...

  8. LeetCode 811. Subdomain Visit Count (子域名访问计数)

    题目标签:HashMap 题目给了我们一组域名,让我们把每一个域名,包括它的子域名,计数. 遍历每一个域名,取得它的计数,然后把它的所有子域名和它自己,存入hashmap,域名作为key,计数作为va ...

  9. 微软的技术态度 -- 从其对于CRT的设计考虑说起(Thought on the CRT - What Microsoft Prefers)

    很多人从C语言学习过来的人都知道,在编写程序时用到的像printf这样的函数,是作为该语言标准库函数提供的,这也是C语言标准中规定的内容.因此,操作系统必须对其保持一定程度上的透明,也就是说,作为一个 ...

  10. 小贝_mysql sql语句优化过程

    sql语句优化 一.SQL优化的一般步骤 (1).通过show status命令了解各种SQL的运行频率. (2).定位运行效率较低的SQL语句-(重点select) (3).通过explain分析低 ...