第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 ...
随机推荐
- jQuery Validate 使用
jQuery Validate 使用 <script src="js/b/js/jquery.validate.js"></script> <styl ...
- Android游戏框架Libgdx使用入门
转载自:http://blog.csdn.net/cping1982/article/details/6176191 Libgdx作者博客:http://www.badlogicgames.com/ ...
- 在mac osX下安装openCV,used for python
OpenCV是个开源的图像处理库,里面的内容多多. 想了解很多其它,请自行百度咯~ 篇blog是记录在mac下.安装openCV.然后使用python来引用openCV库. 环境是: Python 2 ...
- Web实际应用中的编码问题
一. JSP页面有关编码的介绍 ---->>假设不做不论什么设置,页面默认ISO-8859-1编码(Western European). ---->><%@ page c ...
- 使用SetTimer函数为Delphi的Win控件设置时钟
procedure Timertodo(var messag:Tmessage);message WM_TIMER; procedure TForm1.FormCreate(Sender: TObje ...
- oc50--@class1
// // main.m #import <Foundation/Foundation.h> #import "Person.h" int main(int argc, ...
- 阿里云centos系统上安装ftp
最近需要在一台阿里云的云服务器上搭建FTP服务器,在这篇博文中分享一下我们根据实际需求进行的一些配置. ftp软件用的是vsftpd. vsftpd是一款在Linux发行版中最受推崇的FTP服务器程序 ...
- bzoj1725 [Usaco2006 Nov]Corn Fields牧场的安排(状压dp)
1725: [Usaco2006 Nov]Corn Fields牧场的安排 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 714 Solved: 502 ...
- Quartz实现执行任务记录数据库,方便计算任务的执行次数以及成功次数
任务执行实体 /** * 任务执行情况详情 */ public class JobExecuteDetail implements Serializable{ /** * */ private sta ...
- android service--delphixe 10.3
开发中的陷阱: 1. 别放什么 *.wav文件,这个 服务窗口不能随便放东西,不然铁定出现意想不到的结果,比如 无法运行,因为没 ui界面,随意都不知是啥问题. 2. 不能加载 datamodule ...