简单谈谈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 相关文章推荐
通用JS事件写法实现代码
Jan 07 Javascript
JS 控制CSS样式表
Aug 20 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
May 14 Javascript
javascript复制粘贴与clipboardData的使用
Oct 16 Javascript
深入解读JavaScript中的Iterator和for-of循环
Jul 28 Javascript
jQuery实现美观的多级动画效果菜单代码
Sep 06 Javascript
在React框架中实现一些AngularJS中ng指令的例子
Mar 06 Javascript
基于javascript实现文字无缝滚动效果
Mar 22 Javascript
原生js二级联动效果
Jun 20 Javascript
js微信分享实现代码
Oct 11 Javascript
详解Vuex中mapState的具体用法
Sep 28 Javascript
使用Angular Cli如何创建Angular私有库详解
Jan 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
smarty+adodb+部分自定义类的php开发模式
2006/12/31 PHP
PHP开发工具ZendStudio下Xdebug工具使用说明详解
2013/11/11 PHP
10款实用的PHP开源工具
2015/10/23 PHP
php 使用redis锁限制并发访问类示例
2016/11/02 PHP
mysqli扩展无法在PHP7下升级问题的解决
2019/09/10 PHP
JavaScript 面向对象编程(2) 定义类
2010/05/18 Javascript
jqTransform form表单美化插件使用方法
2012/07/05 Javascript
Js控制弹窗实现在任意分辨率下居中显示
2013/08/01 Javascript
jQuery操作表格(table)的常用方法、技巧汇总
2014/04/12 Javascript
js处理表格对table进行修饰
2014/05/26 Javascript
Angular.js中定时器循环的3种方法总结
2017/04/27 Javascript
JavaScript反弹动画效果的实现代码
2017/07/13 Javascript
angularJS的radio实现单项二选一的使用方法
2018/02/28 Javascript
如何优雅的在一台vps(云主机)上面部署vue+mongodb+express项目
2019/01/20 Javascript
vue父子组件通信的高级用法示例
2019/08/29 Javascript
Vue data的数据响应式到底是如何实现的
2020/02/11 Javascript
Js Snowflake(雪花算法)生成随机ID的实现方法
2020/08/26 Javascript
区分vue-router的hash和history模式
2020/10/03 Javascript
[03:10]2014DOTA2 TI马来劲旅Titan首战告捷目标只是8强
2014/07/10 DOTA
Android模拟器无法启动,报错:Cannot set up guest memory ‘android_arm’ Invalid argument的解决方法
2016/07/01 Python
使用python和Django完成博客数据库的迁移方法
2018/01/05 Python
Python内置函数reversed()用法分析
2018/03/20 Python
Python Django中间件,中间件函数,全局异常处理操作示例
2019/11/08 Python
有关HTML5中背景音乐的自动播放功能
2017/10/16 HTML / CSS
HTML5自定义属性的问题分析
2019/08/16 HTML / CSS
Lancer Skincare官方网站:抗衰老皮肤护理
2020/11/20 全球购物
婚礼司仪主持词
2014/03/14 职场文书
幼儿园六一儿童节主持节目串词
2014/03/21 职场文书
农村门前三包责任书
2014/07/25 职场文书
少先队活动总结
2014/08/29 职场文书
九一八事变演讲稿
2014/09/05 职场文书
捐资助学感谢信
2015/01/21 职场文书
教师工作证明范本
2015/06/12 职场文书
手把手教你制定暑期学习计划,让你度过充实的暑假
2019/08/22 职场文书
深入理解python多线程编程
2021/04/18 Python
python保存图片的四个常用方法
2022/02/28 Python