Javascript中的函数中的this值
看下面这段代码会在控制台上输出什么内容?
<script>
var url="fang.com";
var obj={
url:"soufun.com",
func:function(){
return this.url;
}
}; console.log((obj.func)());
console.log((1&&obj.func)())
</script>
答案是
soufun.com
fang.com
今天一同事拿着这段代码,问我为何第二次输出的是"fang.com"。
这段代码只能在非严格模式下执行,那么我们就看看有关this的规范的介绍,Standard ECMA-262 3rd (ECMA-262标准 第三版)
10.1.7 This
There is a this value associated with every active execution context. The this value depends on the caller and the type of code being executed and is determined when control enters the execution context. The this value associated with an execution context is immutable.
对于每个活动执行上下文,都有一个 this 值与其相关联。在控制进入执行上下文时,根据调用者和被执行代码的类型决定这个值。与执行上下文相关联的 this 值是不可改变的。
10.2 Entering An Execution Context
Every function and constructor call enters a new execution context, even if a function is calling itself recursively. Every return exits an execution context. A thrown exception, if not caught, may also exit one or more execution contexts. When control enters an execution context, the scope chain is created and initialised, variable instantiation is performed, and the this value is determined. The initialisation of the scope chain, variable instantiation, and the determination of the this value depend on the type of code being entered.
10.2 进入执行上下文
每个函数和构造器调用都要进入一个新的执行上下文,即使是函数在递归地调用自身。每次返回都会退出执行上下文。未被 catch 的异常抛出有可能退出一个或多个执行上下文。
当控制进入执行上下文时,创建并初始化作用域链,进行变量初始化,并决定 this 值。
作用域链的初始化,变量的初始化和 this 值的决定取决于进入的代码类型。
10.2.1 Global Code
The scope chain is created and initialised to contain the global object and no others.
Variable instantiation is performed using the global object as the variable object and using property attributes { DontDelete }.
The this value is the global object.
10.2.1 全局代码
• 被创建并初始化的作用域链只包含全局代码。
• 进行变量初始化时,把全局对象作为可变对象,属性特征为 { DontDelete }。
• this 值为全局对象。
10.2.2 Eval Code
When control enters an execution context for eval code, the previous active execution context, referred to as the calling context, is used to determine the scope chain, the variable object, and the this value. If there is no calling context, then initialising the scope chain, variable instantiation, and determination of the this value are performed just as for global code. The scope chain is initialised to contain the same objects, in the same order, as the calling context's scope chain. This includes objects added to the calling context's scope chain by with statements and catch clauses.
Variable instantiation is performed using the calling context's variable object and using empty property attributes.
The this value is the same as the this value of the calling context.
10.2.2 求值代码
当控制进入求值代码的执行上下文时,把前一个活动的执行上下文引用为调用上下文,用它决定作用域链、可变对象和 this 值。若调用上下文不存在,就把它当作全局对象,进行作用域链和变量的初始化及 this 值的决定。
• 被创建并初始化的作用域链与调用上下文包含相同的对象,顺序也一样;使用 with 声明或 catch 语句给调用上下文的作用域链添加的对象也包括在内。
• 进行变量初始化时,使用调用上下文的可变对象,属性特征为空。
• this 值与调用上下文的 this 值相同。
10.2.3 Function Code
The scope chain is initialised to contain the activation object followed by the objects in the scope chain stored in the [[Scope]] property of the Function object.
Variable instantiation is performed using the activation object as the variable object and using property attributes { DontDelete }.
The caller provides the this value. If the this value provided by the caller is not an object (note that null is not an object), then the this value is the global object.
10.2.3 函数代码
• 被创建并初始化的作用域链包含一个活动对象,该对象之后是函数对象的[[Scope]]属性存储的作用域链中的对象。
• 进行变量初始化时,把该活动对象作为可变对象,属性特征为 { DontDelete }。
• this 值由调用者提供。若调用者提供的 this 值不是一个对象(注意,null 不是对象),则 this 值为全局对象。
一开始的代码中,代码类型是函数代码,其中this值由调用者提供。
运算符的优先级,因.(属性存取) [](数组下标) ()(函数调用) 都属于同级(最高级)并且是左结合。
对于代码(obj.func)()和obj.func()是一样的。都是先获取obj的方法,再执行。他的调用者是obj。
对于代码(1&&obj.func)(),1&&obj.func是个算式,这个算式返回obj.func的值。那么就相当于
(function(){return this.url;})()
其调用者是window,所以(function(){return this.url;})()的返回值是"fang.com"
参考
http://bclary.com/2004/11/07/
http://zhangbo-peipei-163-com.iteye.com/blog/1773959
创建于2014.10.21,完成时间时间:2014.10.23
Javascript中的函数中的this值的更多相关文章
- eclipse 中main()函数中的String[] args如何使用?通过String[] args验证账号密码的登录类?静态的主方法怎样才能调用非static的方法——通过生成对象?在类中制作一个方法——能够修改对象的属性值?
eclipse 中main()函数中的String[] args如何使用? 右击你的项目,选择run as中选择 run configuration,选择arguments总的program argu ...
- JS中给函数参数添加默认值(多看课程)
JS中给函数参数添加默认值(多看课程) 一.总结 一句话总结:咋函数里面是可以很方便的获取调用函数的参数的,做个判断就好,应该有简便方法,看课程. 二.JS中给函数参数添加默认值 最近在Codewar ...
- 软件测试中LoadRunner函数中的几个陷阱
软件测试 中 LoadRunner 函数中的几个陷阱 1.atof 在 loadrunner 中如果直接用 float f; f=atof("123.00"); lr _outpu ...
- JS中给函数参数添加默认值
最近在Codewars上面看到一道很好的题目,要求用JS写一个函数defaultArguments,用来给指定的函数的某些参数添加默认值.举例来说就是: // foo函数有一个参数,名为x var f ...
- linux中probe函数中传递的参数来源(上)
点击打开链接 上一篇中,我们追踪了probe函数在何时调用,知道了满足什么条件会调用probe函数,但probe函数中传递的参数我们并不知道在何时定义,到底是谁定义的,反正不是我们在驱动中定义的(当然 ...
- js中在一个函数中引用另一个函数中的函数,可以这么做
在另一个函数中,将需要使用的函数绑定在window下 // UEditor $(function () { window.ue = UE.getEditor('editor', { // ue即可成为 ...
- ajax中error函数参数与返回值详解 200 300 400 500
201-206:都表示服务器成功处理了请求的状态代码,说明网页可以正常访问. 200:(成功) 服务器已成功处理了请求.通常,这表示服务器提供了请求的网页. 201:(已创建) 请求成功且服务器已创建 ...
- function 中定义函数的默认返回值,
result有默认值的int类型的为0,string类型的为‘’,tobject类型的为nil等等
- oracle条件参数中 IN函数中的值最大只能为1000个
delete from dep where id in(1,2,3.....) 括号里面字段个数最大只能为1000个
随机推荐
- 微信小程序 - 多地点标识(map)
演示如下: wxml <map id="map" scale="{{scale}}" controls="{{controls}}" ...
- CSS/JavaScript hacks,browserhacks使用
1.网址 http://browserhacks.com/ 2.使用 (1)JavaScript Hacks 浏览器js判断 (2)条件注释hack (3)Media Query Hacks 媒体查询 ...
- Android Camera 使用小结。两种方法:一是调用系统camera app,二是自己写camera程序。
源文链接:http://www.cnblogs.com/franksunny/archive/2011/11/17/2252926.html Android Camera 使用小结 Android手机 ...
- java基础入门-多线程同步浅析-以银行转账为样例
在说之前先普及一下线程是什么? 线程:说白了就是一个任务片段 进程:是一个具有独立功能的程序关于某个数据集合的一次执行活动.一个进程有一个或者多个线程 线程与进程的本质差别就是有么有数据共享空间.线程 ...
- 设计模式之里氏替换原则(LSP)
在java等面向对象编程语言里面,我想继承性应该是一大特色吧!所以今天所要讲解的里氏替换原则主要是针对这一特性而提出来的,当我们定义对象的时候,尽量找出对象之间的相同点,然后将其抽象成基类对象.比如水 ...
- python学习之函数返回值
python中函数返回值的方式有2种: 1.return语句 说明:return语句执行完后,函数后续的代码将不会被执行 2.yield语句 说明:yield语句返回的是一个迭代器对象,可以通过nex ...
- jsdoc — js注释
官方文档 http://usejsdoc.org/ - sublime插件 https://github.com/spadgos/sublime-jsdocs - 生成文档 生成html: (1)安装 ...
- java - day11 - OverRideTest
概念 1.重写:看调用方法的对象:如果调用的是子类对象,则无论父类/子类引用类型,调用的都是重写后的方法,如果想调用父类的方法,用super.方法 来调:如果调用的是父类对象,则调用的是父类重写前的方 ...
- maven项目工程报错:cannot be resolved to a type
1.在本地仓库中,搜索“_maven.repositories”所有匹配项,并彻底删除 2.然后再删除“.lastUpdated”所有匹配项 3.最后再重新在eclipse中执行操作:update d ...
- FreeBSD将SHELL从csh换成bash并支持中文显示
刚准备在FreeBSD下学习Shell,结果发现怎么好多命令都没有,比如declare.后来发现连bash都没有,好像bash用的多一些吧,于是就准备将csh换成bash. 由于没有bash,所以先得 ...