简单谈谈javascript中this的隐式绑定


Posted in Javascript onFebruary 22, 2016

我们先来看一个例子

function foo() {
  console.log( this.a );
}
var obj = {
  a: 2,
  foo: foo
};
obj.foo(); // 2

this指向了obj,因为foo执行时的call-site(可以理解为调用时所在作用域)在obj上面。注意是运行的时候,和在哪里声明的没有关系。

call-site and call-stack

call-site姑且理解为调用域,call-stack为调用栈。如下代码可以辅助我们理解

function baz() {
  // call-stack is: `baz`
  // so, our call-site is in the global scope

  console.log( "baz" );
  bar(); // <-- call-site for `bar`
}

在baz()中调用bar(),所以bar的调用域是baz,此时bar的调用栈只有baz;而baz本身暴露在全局作用域中,所以它的调用域则也在全局作用域中。

function bar() {
  // call-stack is: `baz` -> `bar`
  // so, our call-site is in `baz`
  console.log( "bar" );
  foo(); // <-- call-site for `foo`
}
function foo() {
  // call-stack is: `baz` -> `bar` -> `foo`
  // so, our call-site is in `bar`
  console.log( "foo" );
}
baz(); // <-- call-site for `baz`

理解之后再回头看开头的例子,是不是感觉清晰了很多。其实this只是指向了它的call-site

还有如下玩法:

function foo() {
  console.log( this.a );
}
var obj2 = {
  a: 42,
  foo: foo
};
var obj1 = {
  a: 2,
  obj2: obj2
};
obj1.obj2.foo(); // 42
Implicitly Lost(隐式丢失)
function foo() {
  console.log( this.a );
}
var obj = {
  a: 2,
  foo: foo
};
var bar = obj.foo; // function reference/alias!
var a = "oops, global"; // `a` also property on global object
bar(); // "oops, global"

虽然bar引用了obj上的foo,但实际上相当于是直接对foo引用而已,所以会默认绑定到全局。

function foo() {
  console.log( this.a );
}
function doFoo(fn) {
  // `fn` is just another reference to `foo`
  fn(); // <-- call-site!
}
var obj = {
  a: 2,
  foo: foo
};
var a = "oops, global"; // `a` also property on global object
doFoo( obj.foo ); // "oops, global"
Javascript 相关文章推荐
利用onresize使得div可以随着屏幕大小而自适应的代码
Jan 15 Javascript
jQuery 自动增长的文本输入框实现代码
Apr 02 Javascript
网络之美 JavaScript中Get和Set访问器的实现代码
Sep 19 Javascript
表单JS弹出填写提示效果代码
Apr 16 Javascript
JS、jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例分享
Apr 11 Javascript
jQuery autoComplete插件两种使用方式及动态改变参数值的方法详解
Oct 24 Javascript
bootstrap 模态框(modal)实现水平垂直居中显示
Jan 23 Javascript
js canvas实现适用于移动端的百分比仪表盘dashboard
Jul 18 Javascript
jQuery Validate插件ajax方式验证输入值的实例
Dec 21 jQuery
Node.js创建HTTP文件服务器的使用示例
May 11 Javascript
ES6 系列之 WeakMap的使用示例
Aug 06 Javascript
解决在Vue中使用axios用form表单出现的问题
Oct 30 Javascript
javascript实现一个简单的弹出窗
Feb 22 #Javascript
Js的Array数组对象详解
Feb 22 #Javascript
AngularJS中使用HTML5手机摄像头拍照
Feb 22 #Javascript
JS字符串的切分用法实例
Feb 22 #Javascript
JS实现上下左右对称的九九乘法表
Feb 22 #Javascript
基于Javascript实现倒计时功能
Feb 22 #Javascript
TypeOf这些知识点你了解吗
Feb 21 #Javascript
You might like
PHP OPCode缓存 APC详细介绍
2010/10/12 PHP
PHP删除特定数组内容并且重建数组索引的方法.
2011/03/25 PHP
php实现可以设置中奖概率的抽奖程序代码分享
2014/01/19 PHP
CodeIgniter集成smarty的方法详解
2016/05/26 PHP
基于jquery的回到页面顶部按钮
2011/06/27 Javascript
js判断undefined类型,undefined,null, 的区别详细解析
2013/12/16 Javascript
用js读、写、删除Cookie代码分享及详细注释说明
2014/06/05 Javascript
深入探讨前端框架react
2015/12/09 Javascript
jQuery插件开发精品教程让你的jQuery提升一个台阶
2016/01/27 Javascript
javascript html实现网页版日历代码
2016/03/08 Javascript
Bootstarp 基础教程之表单部分实例代码
2017/02/03 Javascript
node.js入门学习之url模块
2017/02/25 Javascript
微信小程序 弹窗自定义实例代码
2017/03/08 Javascript
利用canvas实现的加载动画效果实例代码
2017/07/05 Javascript
angular2+node.js express打包部署的实战
2017/07/27 Javascript
vue watch普通监听和深度监听实例详解(数组和对象)
2018/08/16 Javascript
微信小程序用户信息encryptedData详解
2018/08/24 Javascript
vue循环数组改变点击文字的颜色
2019/10/14 Javascript
纯 JS 实现放大缩小拖拽功能(完整代码)
2019/11/25 Javascript
解决vue中的无限循环问题
2020/07/27 Javascript
[03:26]《DAC最前线》之EG经理自述DOTA2经历
2015/02/02 DOTA
详解Python 2.6 升级至 Python 2.7 的实践心得
2017/04/27 Python
PyQt5笔记之弹出窗口大全
2019/06/20 Python
python中while和for的区别总结
2019/06/28 Python
react+django清除浏览器缓存的几种方法小结
2019/07/17 Python
Django使用模板后无法找到静态资源文件问题解决
2019/07/19 Python
解决keras GAN训练是loss不发生变化,accuracy一直为0.5的问题
2020/07/02 Python
iframe跨域的几种常用方法
2019/11/11 HTML / CSS
世界最大的海报和艺术印刷商店:AllPosters.com
2017/02/01 全球购物
英国卫浴商店:Ergonomic Design
2019/09/22 全球购物
extern是什么意思
2016/03/10 面试题
2014社区三八妇女节活动方案
2014/03/30 职场文书
员工升职自荐信
2015/03/27 职场文书
优秀共产党员事迹材料2016
2016/02/29 职场文书
祝福语集锦:给百岁老人祝寿贺词
2019/11/19 职场文书
python通过函数名调用函数的几种方法总结
2021/06/07 Python