第2章 this 、 call 和 apply
第一部分 基础知识
第2章 this 、 call 和 apply
2.1 this
JavaScript的 this 总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。也就是说声明时不知道,运行时才知道。
this 的指向大致可以分为以下 4种:
作为对象的方法调用。
<script type="text/javascript">
//当函数作为对象的方法被调用时, this 指向该对象:
var obj = {
a:1,
getA:function(){
console.log(this === obj);
console.log(this.a);
}
}
obj.getA();
</script>
作为普通函数调用。
<script>
//作为普通函数调用
window.name = 'globalName';
var getName = function(){
return this.name;
}
console.log(getName());
var getId = function( id ){
return document.getElementById( id );
};
getId( 'div1' );
</script>
构造器调用。
<script>
var MyClass = function(){
this.name = 'sven';
};
var obj = new MyClass();
alert ( obj.name ); // 输出:sven
</script>
Function.prototype.call 或 Function.prototype.apply 调用。
<script>
var obj1 = {
name: 'sven',
getName: function(){
return this.name;
}
};
var obj2 = {
name: 'anne'
};
console.log( obj1.getName() ); // 输出: sven
console.log( obj1.getName.call( obj2 ) ); // 输出:anne
</script>
2.2 call 和 apply
ECAMScript 3给 Function 的原型定义了两个方法,它们是 Function.prototype.call 和 Function.prototype.apply 。
2.2.1 call 和 apply 的区别
apply 接受两个参数,第一个参数指定了函数体内 this 对象的指向,第二个参数为一个带下标的集合,这个集合可以为数组,也可以为类数组, apply 方法把这个集合中的元素作为参数传递给被调用的函数。
2.2.2 call 和 apply 的用途
1. 改变 this 指向
<script>
var obj1 = {
name: 'sven'
};
var obj2 = {
name: 'anne'
};
window.name = 'window';
var getName = function(){
alert ( this.name );
};
getName(); // 输出: window
getName.call( obj1 ); // 输出: sven
getName.call( obj2 ); // 输出: anne
</script>
2. Function.prototype.bind
Function.prototype.bind = function(){
var self = this,// 保存原函数
context = [].shift.call(arguments);// 需要绑定的 this 上下文
args = [].slice.call(arguments);// 剩余的参数转成数组
// 返回一个新的函数
return function(){
// 执行新的函数的时候,会把之前传入的 context 当作新函数体内的 this
// 并且组合两次分别传入的参数,作为新函数的参数
return self.apply(context, [].concat.call(args, [].slice.call(arguments)));
}
} var obj1 = {
name:'john'
};
var func1 = function(a,b,c,d){
console.log(this.name);
console.log([a,b,c,d]);
}.bind(obj1, 1,2); func1(3,4);
3. 借用其他对象的方法
第一种场景是“借用构造函数”
//借用构造函数
var A = functiono(name){
this.name = name;
}
var B = function(){
A.apply(this, arguments);
} B.prototype.getName = function(){
return this.name;
} var b = new B('john');
console.log(b.getName());
第二种场景借用 Array.prototype 对象上的方法
//借用其它对象
(function(){
Array.prototype.push.call(arguments, 3);
console.log(arguments);
})(1,2);
第2章 this 、 call 和 apply的更多相关文章
- js call与apply的区别-Tom
.apply和.call方法是在函数原型中定义的两个方法(因此所有的函数都可以访问它)允许去手动设置函数调用的this值,他们用接受 的第一个参数作为this值,this 在调用的作用域中使用.这两个 ...
- Angular中ngModel的$render的详解
在我开始着手ngModel的领域时候,有一个问题很令我纠结,那就是$render()到底是做什么的呢?查了很多资料都只是简单的描述一下,这就令我很纠结了,终于在一个阳光明媚的晚上,我终于解决了这个大问 ...
- angularjs杂谈
1.MVVM的看法:我给view里面各种控件也定义一个对应的数据对象,这样,只要修改这个数据对象,view里面显示的内容就自动跟着刷新,而在view里做了任何操作,这个数据对象也跟着自动更新. Vie ...
- 洗礼灵魂,修炼python(11)--python函数,模块
前面的章节你如果看懂了,基本算是入门了七八了,不过如果你以为python就这么点东西,你觉得很简单啊,那你就错了,真正的东西在后面,前面我说的几大核心其实也不是多么高深多么厉害的,那些东西是基础很常用 ...
- 使用 for 循环
for 循环通过迭代一个给定向量或列表,重复执行某个表达式.for 循环的语法是这样的:for (var in vector) {expr}var 遍历 vector 中的各个元素值,expr 被反复 ...
- 7第七章联接和APPLY运算符(转载)
7第七章联接和APPLY运算符 原文链接 本文由豆约翰博客备份专家远程一键发布
- 《On Lisp》第四章第三节图4.6中的rmapcar函数中展现的apply陷阱
(defun rmapcar (fn &rest args) (if (some #'atom args) (apply fn args) (apply #'mapcar #'(lambda ...
- Tsql2008查询性能优化第一章---APPLY
APPLY运算符涉及以下两个步骤中的一步或两步(取决于APPLY的类型): 1.A1把右表表达式应用于左表的行. 2.A2:添加外部行. Ap ...
- ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由
原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...
随机推荐
- Intellij Idea 13:运行Clojure的repl环境
准备工作:1. 安装cursive插件. a) 官网地址:https://cursiveclojure.com/userguide b) 插件的Reposi ...
- MVC.Net:对MVC5部署时出现403.14错误的解决方法
当我们部署MVC5到IIS 7的时候,有时会出现403.14的错误,如下图: 对于这个错误的解决方法就是在应用程序的web.config的system.webServer节点中加入这一句: <m ...
- 2.2-VLAN间路由
2.2-VLAN间路由 第一代LAN间的通信: 不支持VLAN的交换机:由一个路由器和几个交换机组成,每个交换机的所有端口都同属于一个网段/LAN:在路由器上有几个网段就有几个与之相对 ...
- [Cypress] Interact with Hidden Elements in a Cypress Test
We often only show UI elements as a result of some user interaction. Cypress detects visibility and ...
- [React] Refactor a connected Redux component to use Unstated
In this lesson, I refactor a simple Counter component connected to Redux to use Unstated instead. I ...
- POJ 2891 Strange Way to Express Integers 中国剩余定理解法
一种不断迭代,求新的求余方程的方法运用中国剩余定理. 总的来说,假设对方程操作.和这个定理的数学思想运用的不多的话.是非常困难的. 參照了这个博客的程序写的: http://scturtle.is-p ...
- ActionBar第一课简单介绍
.ActionBar简单介绍 ActionBar是显示在界面顶部的标题栏. 官方推荐开发者尽量使用 ActionBar代替OptionsMenu和TabHost. 典型应用方式有: 使用导航栏中的应用 ...
- HibernateBaseDAO
HibernateBaseDAO接口 package com.iotek.homework.dao; import java.io.Serializable; import java.util.Lis ...
- 5200 fqy的难题----2的疯狂幂
5200 fqy的难题----2的疯狂幂 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description ...
- VS2010中文注释带红色下划线的解决方法
环境:Visual Studio 2010 问题:代码中出现中文后会带下划线,很多时候感觉很不舒服.找了很久的原因没找到,后来无意中在VisualAssist X里找到了解决办法. 1.安装完Visu ...