Javascript中的函数中的this值

看下面这段代码会在控制台上输出什么内容?

 1 <script>
 2     var url="fang.com";
 3     var obj={
 4         url:"soufun.com",
 5         func:function(){
 6             return this.url;
 7         }
 8     };
 9
10     console.log((obj.func)());
11     console.log((1&&obj.func)())
12 </script>

答案是

1 soufun.com
2 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

时间: 2024-07-30 06:41:54

Javascript中的函数中的this值的相关文章

软件测试中LoadRunner函数中的几个陷阱

软件测试 中 LoadRunner 函数中的几个陷阱 1.atof 在 loadrunner 中如果直接用 float f; f=atof("123.00"); lr _output_message("%f",f); 输出的结果会是1244128.00,根本不是我们想要的. 因为float,double型在不同的平台下长度不一样,所以在loadrunner 软件测试中LoadRunner函数中的几个陷阱 1.atof 在loadrunner中如果直接用 float

继承过程中对函数中this的认识

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 </head> 7 <body> 8 <script> 9 var a = { 10 x:10, 11 cc:function(z){ 12 return this

苹果浏览器Safari对JS函数库中newDate()函数中的参数的解析中不支持形如“2020-01-01”形式

苹果浏览器safari对new Date('1937-01-01')不支持,用.replace(/-/g, "/")函数替换掉中划线即可 如果不做处理,会报错:invalid date 本解决方案参考:http://stackoverflow.com/questions/4310953/invalid-date-in-safari

Python中print函数中中逗号和加号的区别

先看看print中逗号和加号分别打印出来的效果.. 这里以Python3为例 1 print("hello" + "world") helloworld 1 print("hello", "world") hello world 这里发现加号的作用是连接字符串 而逗号相当于用空格连接字符串. 尝试一下不同数据类型的操作.. 1 print("hello" + 123) TypeError: must be

泊松表面重建中主函数中部分代码分析-关于内存设置

1 //总体来看是和内存设置有关的 2 #if defined(WIN32) && defined(MAX_MEMORY_GB) 3 if( MAX_MEMORY_GB>0 ) 4 { 5 //SIZE_T是ULONG_PTR类型又是unsigned __int64类型取值范围为2到2的64次方,貌似和64为操作系统支持的理论内存值有关系 6 SIZE_T peakMemory = 1; 7 peakMemory <<= 30;//peakMemory等于peakMemo

React中render函数中变量map中事件无法关联的解决办法

如下所示的代码,Input的checkbox可以正常显示3个,但是都无法和 handleChange关联上. 由于代码无法正常显示,我用图片 var Input = ReactBootstrap.Input; var TestCom = React.createClass({ getInitialState: function() { return {value: 'Hello!', value2: 'nihao2' }; }, handleChange: function(event) { v

AE中OnAfterDraw函数中绘制点线面的相关代码

需要提前得到一个IActiveview类型的变量activeView 1.点绘制代码 其中getoffDrawList装载的是IFeature类型的点要素 1 if (getoffDrawList != null && getoffDrawList.Count > 0 ) 2 { 3 IRgbColor getOnOffPtcolor = new RgbColorClass(); 4 getOnOffPtcolor.Red = 0; 5 getOnOffPtcolor.Green =

urllib模块中parse函数中的urlencode和quote_plus方法

本来只是向看一下quote_plus的作用,然后发现urlencode方法也是很方便的一个组合字符串的方法首先是介绍一下urlencode,他是将一些传入的元素使用&串联起来,效果如下: >>>params = { "appid": 1, "mch_id": 1, "body": 1, "out_trade_no": 1, "total_fee": 1, "spbill_

把数据写入txt中 open函数中 a与w的区别

a: 打开一个文件用于追加.如果该文件已存在,文件指针将会放在文件的结尾. 也就是说,新的内容将会被写入到已有内容之后.如果该文件不存在,创建新文件进行写入. w:  打开一个文件只用于写入.如果该文件已存在则打开文件,并从开头开始编辑, 即原有内容会被删除.如果该文件不存在,创建新文件. 简单说a类似于append,每次运行在原有基础上增加,而w是覆盖. open模式设为a运行两次 代码: 1 filename = 'test.txt' 2 file = open(filename, 'a')