简单谈谈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 相关文章推荐
jQuery(非HTML5)可编辑表格实现代码
Dec 11 Javascript
MultiSelect左右选择控件的设计与实现介绍
Jun 08 Javascript
jquery设置元素的readonly和disabled的写法
Sep 22 Javascript
Jquery ajaxStart()与ajaxStop()方法(实例讲解)
Dec 18 Javascript
js实现局部页面打印预览原理及示例代码
Jul 03 Javascript
谈谈javascript中使用连等赋值操作带来的问题
Nov 26 Javascript
ECharts仪表盘实例代码(附源码下载)
Feb 18 Javascript
轮播图组件js代码
Aug 08 Javascript
浅谈jQuery中的checkbox问题
Aug 10 Javascript
JavaScript 动态三角函数实例详解
Jan 08 Javascript
详解JavaScript的BUG和错误
May 07 Javascript
vue监听input标签的value值方法
Aug 27 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
2019年中国咖啡业现状与发展趋势
2021/03/04 咖啡文化
php数据库连接
2006/10/09 PHP
7个超级实用的PHP代码片段
2011/07/11 PHP
Yii框架获取当前controlle和action对应id的方法
2014/12/03 PHP
PHP版微信公众平台红包API
2015/04/02 PHP
yii2.0数据库迁移教程【多个数据库同时同步数据】
2016/10/08 PHP
laravel5.5添加echarts实现画图功能的方法
2019/10/09 PHP
laravel 多图上传及图片的存储例子
2019/10/14 PHP
laravel框架中视图的基本使用方法分析
2019/11/23 PHP
jQuery版Tab标签切换
2011/03/16 Javascript
js实现单一html页面两套css切换代码
2013/04/11 Javascript
jquery.Ajax()方法调用Asp.Net后台的方法解析
2014/02/13 Javascript
JavaScript中对象property的读取和写入方法介绍
2014/12/30 Javascript
jquery根据一个值来选中select下的option实例代码
2016/08/29 Javascript
纯JS焦点图特效实例(可一个页面多用)
2016/12/07 Javascript
Vue获取DOM元素样式和样式更改示例
2017/03/07 Javascript
jQuery实现的监听导航滚动置顶状态功能示例
2018/07/23 jQuery
layui点击按钮添加可编辑的一行方法
2018/08/15 Javascript
微信小程序CSS3动画下拉菜单效果
2018/11/04 Javascript
Vue项目页面跳转时浏览器窗口上方显示进度条功能
2020/03/26 Javascript
Vue解决echart在element的tab切换时显示不正确问题
2020/08/03 Javascript
详解nginx配置vue h5 history去除#号
2020/11/09 Javascript
[02:21]十步杀一人,千里不留行——DOTA2全新英雄天涯墨客展示
2018/08/29 DOTA
Python使用cookielib模块操作cookie的实例教程
2016/07/12 Python
python list是否包含另一个list所有元素的实例
2018/05/04 Python
关于多元线性回归分析——Python&amp;SPSS
2020/02/24 Python
IDLE下Python文件编辑和运行操作
2020/04/25 Python
css3 实现圆形旋转倒计时
2018/02/24 HTML / CSS
html5仿支付宝密码框的实现代码
2017/09/06 HTML / CSS
Mountain Warehouse波兰官方网站:英国户外品牌
2019/08/29 全球购物
一些高难度的SQL面试题
2016/11/29 面试题
商铺消防安全责任书
2014/07/29 职场文书
教师政风行风评议心得体会
2014/10/21 职场文书
《牧场之国》教学反思
2016/02/22 职场文书
MySQL基础(二)
2021/04/05 MySQL
python第三方网页解析器 lxml 扩展库与 xpath 的使用方法
2021/04/06 Python