JavaScript学习随笔--函数执行上下文
来源:互联网 发布:linux重启命令 reboot 编辑:程序博客网 时间:2024/06/08 01:57
JavaScript中的函数执行上下文
- 函数上下文就是函数中的this
- 函数中的this指向和函数的定义位置、执行位置无关
- 函数中this的指向只取决于函数的调用方式
所有的JavaScript函数执行时都是有上下文的。那么,什么是函数的执行上下文呢?简单说来就是函数中this所指向的对象。我们来看下面这段代码:
function f1(){ console.log(this.name);}
这段代码最终会打印出什么来呢?也就是这里的this指向谁呢?在定义的时候我们并不知道,函数最终的调用方式决定this的指向。一般说来JavaScript里有4中调用函数的方式:
- 直接调用
- 作为对象的方法调用
- 通过函数对象的apply或者call方法调用
- 通过关键词new调用
以直接调用方式执行的函数上下文指向全局对象。一般情况下全局对象中并不存在一个name的属性,所以this.name的值是undefined。
function f1(){ console.log(this.name);}f1();//console should print "undefined"
作为对象方法调用的函数上下文指向对象本身。例如,我们在这里我们定义了一个对象o,o有一个属性name,还有一个方法f1,这个方法f1指向前面定义的全局函数f1。那么这里的this将指向对象o,this.name的值就是o.name的值,所以打印出来的是o.name的值。
function f1(){ console.log(this.name);}var o ={ name:"qwan", f1:f1};o.f1();//console will print "qwan"
通过函数对象的apply或者call方法调用函数可以用apply的第一个参数显式指定上下文。在这里我们定义了两个对象o和p,都只包含一个name属性。我们可以看到,f1.apply(o)调用时this指向o,this.name的值就是o.name,参数换成p最后打印的就是p.name的值。
function f1(){ console.log(this.name);}var o ={ name:"qwan"};var p ={ name:"bob"};f1.apply(o);//console will print "qwan"f1.apply(p);//console will print "bob"
函数的最后一种调用方式是通过关键词new调用,通过new调用的函数就是我们通常说的构造函数,在调用之前会自动创建一个空对象,这个空对象就是函数的上下文,调用完后返回这个对象。
function f1(name){ this.name = name; console.log(this.name);}var o = new f1("qwan");//will print "qwan" hereconsole.log(o.name);// also print "qwan" herevar p = new f2("bob");//will print "bob" hereconsole.log(p.name);//also print "bob" here
在这我们能清楚的看到函数不同的调用方式对函数上下文的影响。那么函数定义的位置会不会影响函数执行时的上下文呢?答案是否定的,JavaScript中函数的上下文只取决于函数的调用方式,与函数定义的位置无关。上面例子中使用的是全局域中定义的函数,我们还可以将函数定义在对象中。请看下面的例子:
var o ={ name:"qwan", f:function(){console.log(this.name);}//函数定义成对象的方法};var p ={ name:"bob"};o.f.apply(o);//console will print "qwan"o.f.apply(p);//console will print "bob"
至此我们基本搞清楚了JavaScript中函数上下文的指向问题。总结一下,直接调用函数时其上下文是全局对象;作为对象方法调用时其上下文是对象本身;使用函数对象的apply或者call方法调用函数其上下文是apply或者call方法的第一个参数;通过new关键词调用的函数上下文是自动创建的一个空对象,调用完之后返回上下文对象。
接下来,我们来研究一个实例,代码如下:
function invoke(f){ f();}var o ={ name:"qwan", f:function(){console.log(this.name);}//函数定义成对象的方法};invoke(o.f);
在这个例子中最终打印出来的this.name的值会是什么呢? 应该是”undefined”,你答对了吗?因为在这里f是直接调用的,所以this指向全局对象。但是实际使用过程中,程序员的意图往往是希望f调用的时候使用的上下文是o,这又如何实现呢?请看下面的代码:
function invoke(f){ f();}function hitch(o,f){ return function(){ return f.apply(o); };}var o ={ name:"qwan", f:function(){console.log(this.name);}//函数定义成对象的方法};invoke(hitch(o,o.f));
hitch函数返回了一个函数,这个函数体里显式设置了函数o.f的执行上下文为o,所以最后打印的值是o.name。
- JavaScript学习随笔--函数执行上下文
- javascript的函数执行上下文及this
- JavaScript的执行上下文
- JavaScript的执行上下文
- JavaScript 执行上下文环境
- JavaScript中的执行上下文
- Javascript ES3执行上下文
- JavaScript执行上下文
- JavaScript的执行上下文
- JavaScript上下文执行对象
- JavaScript执行上下文
- JavaScript执行上下文,执行上下文栈
- 深入理解JavaScript执行上下文、函数堆栈、提升的概念
- 深入理解JavaScript执行上下文、函数堆栈、提升的概念
- JavaScript学习--Item19 执行上下文(execution context)
- JavaScript学习随笔--函数作用域
- JavaScript 函数的上下文
- 了解JavaScript的执行上下文
- Android实现C/S聊天室
- 140. Word Break II
- HDU 1729 Stone Game (sg函数)
- C++之set用法总结
- Android中使用ExpandableListView实现好友分组
- JavaScript学习随笔--函数执行上下文
- 利用cmd窗口查询安卓手机数据库文件
- AIDL和四大组件的区别
- js之中介模式
- 韩信点兵
- 哪些情况下索引会失效?
- mySql数据库语句大全
- 简单的通讯录(有bug)
- 根据wsdl反向生成webservice服务端(3种方法)