首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

ECMA-262-3 详解:3、This

(我们一些文章甚至是关于Javascript书籍中看到,他们指出:this 值取决于函数如何定义:如果是一个全局函数, this 指向全局对象,如果是一个对象方法, this 总是指向这个对象。...foo.bar();foo['bar'](); 计算中间返回值中,引用类型对应值如下: var fooBarReference = { base: foo, propertyName: 'bar...相似的情况也出现在属性访问中: var foo = { bar: function() {return this};}; foo.bar(); // foo 同样,我们拥有一个引用类型值,其base是...那么,为什么有一个属性访问器了,中间值也是一个引用类型值,某些调用中,我们得到 this 值不是base对象而是global。...但是,这种表现在 ECMA-262-3 中被认为是一个bug,并且 ECMA-262-5 中被修复修复后,在给定活动中, this 值指向是全局对象而不是 catch 对象。

48920
您找到你想要的搜索结果了吗?
是的
没有找到

你不知道this(2)

我们可以通过分析调用位置来看看foo()是如何调用代码中,foo()是直接使用不加任何修饰符函数引用进行调用,因此只能使用默认绑定,无法引用其他规则。...foo()声明方式,及其之后是如何被当作引用属性添加到obj中。...var a = "oops, global"; // a 是全局对象属性 bar(); // "oops, global" 虽然bar是obj.foo一个引用,但是实际上,它引用foo函数本身,...之后我们会介绍如何通过固定this来修复(这里是双关,"修复"和"固定"英语单词都是fix)这个问题。...显示绑定 就像我们刚才看到那样,分析隐式绑定时,我们必须在一个对象内部包含一个指向函数属性,并通过这个属性间接引用函数,从而把this间接(隐式)绑定到这个对象上。

49710

你不知道JavaScrpit(上卷) 随记(二)

代码中,foo()是 直接使用不带任何修饰函数引用进行调用,因此只能使用默认绑定。...首先需要注意foo()声明方式,及其之后时如何被当作引用属性添加到obj中。...然而调用位置会使用obj上下文来 引用函数,因此你可以说 函数被调用时obj对象 "拥有"或"包含"函数引用。无论你如何称呼,当foo()被调用时, 它前面确实加上了对obj引用。...注意: 对象属性引用链上只有上一层或者说最后一层调用位置中起效果。...(fn, delay) { // wait delay fn() // <--调用位置 } 规则3: 显式绑定 分析 隐式绑定 时,我们必须在一个对象内部包含一个指向函数属性,并通过这个属性间接引用函数

31330

JavaScript范围链中标识符解析和闭包

进入bar(),bar.VO.scopeChain是[bar.VO, foo.VO, global.VO]。...在这篇文章中,我们已经介绍了scope chain其lexical环境细节,以及如何closures和variable resolution工作。本文其余部分将介绍与上述相关一些有趣情况。...alert(bar.a); } } foo()(); // 'Set from foo()' 第5行a全局对象上创建属性bar,并将其值设置为'Set from foo()'。...它 bar 全局范围内发现,并继续搜索bar名为属性a。然而,a从来没有设置过bar,所以解释器遍历对象原型链,并且找到a被设置Object.prototype。...通函 这导致我们关闭,以及程序中循环引用可能性,这是用于描述一个对象引用另一个对象情况术语,并且该对象指向第一个对象。

94410

深入理解JavaScript中this

前面的输出很简单,不用多说,重点想说foo.count这个值,他结果是0。可能会出乎一部分意料,你可能认为foo中this只应该是foo,如果你这么想就错了。...我们知道,声明全局作用域中变量就是全局对象一个同名属性全局作用域中this.a和a是相同。我们看到他最终输出结果是2,就说明调用foo函数时,this.a被解析成了全局变量a。...首先需要注意foo() 声明方式,及其之后是如何被当作引用属性添加到 obj 中。...然而,调用位置会使用 obj 上下文来引用函数,因此你可以说函数被调用时 obj 对象“拥有”或者“包含”它。 无论你如何称呼这个模式,当 foo() 被调用时,它落脚点确实指向 obj 对象。...var a = "oecom"; // a 是全局对象属性 bar(); // "oecom" 上面这段代码就是一种隐式丢失,这是因为bar实际上是对foo一个引用,他就相当于foo函数,调用bar

48030

《你不知道js(上卷)》笔记2(this和对象原型)

bar 中 console.log( "foo" ); } baz(); // <-- baz 调用位置 1.1 绑定规则 默认绑定 声明全局作用域中变量就是全局对象一个同名属性...} doFoo( obj.foo ); // "oops, global" bar是obj.foo一个引用bar()其实是一个不带任何修饰函数调用。...原型 JavaScript中对象有一个特殊 [[Prototype]] 内置属性,其实就是对于其他对象引用。几乎所有的对象创建时 [[Prototype]] 属性都会被赋予一个非空值。...=== Foo; // true Foo.prototype默认有一个公有并且不可枚举属性.constructor,这个属性引用是对象关联函数。...现在没有 Bar.prototype.constructor 了 // 如果你需要这个属性的话可能需要手动修复一下它 Bar.prototype = Object.create( Foo.prototype

67710

《你不知道JavaScript(上)之原型对象》读书笔记

如果无论如何都没有找到名称相同属性,那 [[Get]] 操作会返回值 undefined[[put]] 被触发时,实际行为取决于许多因素,包括对象中是否已经存在这个属性(这是最重要因素)。... ES5 中可以使用 getter 和 setter 部分改写默认操作,但是只能应用在单个属性上,无法 应用在整个对象上。getter 是一个隐藏函数,会在获取属性值时调用。...,这个属性引用是对象关联函数(本例中是 Foo)。...现在没有 Bar.prototype.constructor 了 // 如果你需要这个属性的话可能需要手动修复一下它Bar.prototype.myLabel = function() { return...通常来说,这个链接作用是:如果在对象上没有找到需要属性或者方法引用,引擎就 会继续 [[Prototype]] 关联对象上进行查找。

62430

前端必备,25个最基本JavaScript面试问题及答案

1.使用 typeof bar === "object" 来确定 bar 是否是对象潜在陷阱是什么?如何避免这个陷阱?...严格模式下,引用 null或未定义 this 值会抛出错误。 不允许重复属性名称或参数值。...当检测到对象(例如,var object = {foo: "bar", foo: "baz"};)中重复命名属性,或检测到函数中(例如,function foo(val1, val2, val1){}...也不会抛出错误,因为代码其余部分是完全有效,即使它没有得到调用或做任何事情(相当于它就是是一个未使用代码块,定义了等同于字符串 "hello"属性 bar)。...你如何可靠地测试一个值是否等于 NaN ? NaN 属性代表一个“不是数字”值。

91730

JS入门难点解析7-this

如果不相信,大家可以最后一行尝试输出window.count。 这个例子说明this并不能单纯理解为指向这个函数本身。不过,既然this不是指向函数本身,我们函数内部如何引用函数本身呢?...); } foo(); // undefined 这段代码本意是想,foo全局定义,那么this就指向全局,this.bar就可以调用全局中定义bar,而bar执行时候呢正好是foo执行上下文...如果调用表达式包含一个提取属性动作,那么它就是被当做一个方法来调用。要记住,对象属性引用链中只有最顶层或者说最后一层会影响调用位置。...就是函数进入函数执行上下文时才会进行this绑定,也就是这个函数调用以后才会进行this绑定。而此处仅仅是做了引用赋值,然后进行了bar独立调用。...那么如何防止这种隐式丢失呢?只要想办法让this始终指向其属性拥有者即可。当然我们也可以让this指向任何事先设定对象,做到一种强制绑定,也就是所谓硬绑定。

71710

考虑闭包情况下JS变量存储栈与堆区分

,为了保证变量不被销毁,堆中先生成一个对象就叫 Scope 吧,把变量作为 Scope 属性给存起来。...在上述过程中 foobar、obj,都是变量,变量代表一种引用关系,其本身值并不确定。 那么如果我将一个变量值赋值给另一变量,会发生什么?...修改为变量 foo = bar 如上图所示,仅仅是将 foo 引用地址修改了而已。 const 工作机制 const 为 ES6 新出变量声明一种方式,被 const 修饰变量不能改变。...比如说以下代码: const foo = 'foo'; foo = 'bar'; // Error 如上图关系图所示,foo 不能引用到别的地址值。...那好现在是否能解决你对下面代码困惑: const obj = { foo: 1, bar: 2 }; obj.foo = 2; 其 obj 所引用地址并没有发生变化,发生变部分为另一区域

77020

你为什么学不好闭包

从具体实现上来说,对于函数 bar 而言,闭包对象「Closure (foo)」引用存在于自身 [[Scopes]] 属性中。也就是说,只要函数体 bar 在内存中持久存在,闭包就会持久存在。...当函数 foo 执行,会创建函数体 bar,并作为 foo 返回值。foo 调用完毕,则对应创建执行上下文会被回收,此时 bar 作为 foo 执行上下文部分,自然也会被回收。...也就意味着,即使 foo 执行完毕,foo 上下文会被回收,但是由于函数 bar 有新方式保存引用,那么即使函数体 bar 是属于 foo 上下文部分,它也不会被回收,而会在内存中持续存在。...全局上下文中,保留 foo 执行结果,也就是 内部函数 bar 引用 var bar1 = foo() // 多次执行 bar1() bar1() bar1() // 全局上下文中,保留...虽然 bar1 与 bar2 都是保存 foo 执行结果返回 bar 函数引用。但是他们对应函数体却不是同一个。

8110

开源图书《Python完全自学教程》8.3.2实例属性

Foo 实例化时,通过类初始化方法 __init__() 所创建实例属性,因实例不同而不同,故此属性也称为动态属性,对应于类属性“静态”特征——类属性也称为静态属性。...__dict__ {'name': 'ruby'} 通过实例名称能对该实例属性进行修改、增加、删除操作。8.3.1节已经看到,通过实例名称也能访问到类属性名称。...那么,是否可以对该类属性值进行修改呢?比如: >>> j.lang 'pascal' 若做如下操作,结果会如何?...还要注意,前面演示中所引用对象是不可变对象。如果引用了可变对象,结果会不一样。 >>> class Bar: ......__dict__ {} 两次实例化类 Bar ,分别得到了变量 m 和 n 引用两个实例对象,且这两个实例下均没有名为 lst 属性

34030

js面试跳跳题

= Symbol('bar'); s1.toString() // "Symbol(foo)" s2.toString() // "Symbol(bar)" 引用类型(object 类型) Object...Array Date RegExp Function等等 引用类型值是储存在堆中(heap),但是栈内存中保存着一个堆内存对象引用也可以说是那个对象指针(即地址),所以我们常常实际操作引用而不是操作实际对象...这是因为baz这个变量并没有bar这个属性,而baz此时只被定义,没有被赋值,因此baz也是undefined。...(答案未知) 创建一个空对象 将构造函数this赋给新对象(因此this就指向了这个新对象) 执行构造函数中代码(为这个新对象添加属性) 如果这个函数有返回值,则返回;否则,就会默认返回新对象 参考链接...(重新堆中创建内存,拷贝前后对象基本数据类型互不影响,但拷贝前后对象引用类型因共享同一块内存,会相互影响。)

12810

Python 中作用域规则和闭包简析

上述函数定义中只有b和c两个变量赋值,那调用函数是如何判断a值呢?这涉及到函数作用域规则。...不过与之前例子不同是,函数foo中我们还嵌套了一个函数bar,并且还定义了两个变量,这个函数是作为函数foo返回值。...而函数barfoo返回值,只引用了变量a,因此bar.func_code.co_freevars中便只包含变量a。...内部函数和外部函数co_freevars、co_cellvars对应关系,使得函数编译过程中内部函数具有了一个闭包特殊属性__closure__(底层中对此有相关实现)。...__closure__属性是一个由cell对象组成元组,包含了由多个作用域引用变量。可以做以下验证: >>> foo.

83340

以纯二进制形式在内存中绘制一个对象

一、引用类型实例内存布局 二、以二进制形式创建对象 三、字节数组与实例状态同一性 四、ObjHeader针对哈希被同步状态缓存 一、引用类型实例内存布局 从内存布局角度来看,一个引用类型实例由如下图所示部分组成...具体实现体现在如下所示Create方法中,该方法根据指定属性值创建一个Foobar对象。除了用来提供两个属性foobar参数之外,它还通过输出参数bytes返回整个实例字节序列。...{ get; set; } public int Bar { get; set; } } 根据上述针对内存布局介绍,我们知道任何一个Foobar实例x64机器中都映射位一段连续24字节内存...我们演示程序调用了Create创建了一个FooBar属性分别为1和2Foobar对象,并得到它真正映射在内存中字节序列。...三、字节数组与实例状态同一性 对于我们定义Create方法来说,由于通过输出参数返回字节数字就是返回Foobar对象在内存中映射,所以Foobar状态(FooBar属性)发生改变后,字节数组内容也会发生改变

22020
领券