简单谈谈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 相关文章推荐
在JavaScript中正确引用bind方法的应用
May 11 Javascript
ECMAScript6函数默认参数
Jun 12 Javascript
jQuery实现瀑布流布局详解(PC和移动端)
Sep 01 Javascript
javascript实现拖动元素交换位置
Nov 29 Javascript
移动手机APP手指滑动切换图片特效附源码下载
Nov 30 Javascript
浅谈Angularjs link和compile的使用区别
Oct 21 Javascript
设置jquery UI 控件的大小方法
Dec 12 Javascript
js实现做通讯录的索引滑动显示效果和滑动显示锚点效果
Feb 18 Javascript
微信小程序http连接访问解决方案的示例
Nov 05 Javascript
vue项目创建步骤及路由router
Jan 14 Javascript
es6中使用map简化复杂条件判断操作实例详解
Feb 19 Javascript
教你一步步实现一个简易promise
Nov 02 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之第八天
2006/10/09 PHP
一些常用的php简单命令代码集锦
2007/09/24 PHP
在JavaScript中调用php程序
2009/03/09 PHP
解析PHP实现多进程并行执行脚本
2013/06/18 PHP
基于xcache的配置与使用详解
2013/06/18 PHP
那些年我们错过的魔术方法(Magic Methods)
2014/01/14 PHP
PHP中使用hidef扩展代替define提高性能
2015/04/09 PHP
php 升级到 5.3+ 后出现的一些错误,如 ereg(); ereg_replace(); 函数报错
2015/12/07 PHP
CodeIgniter针对数据库的连接、配置及使用方法
2016/03/03 PHP
PHP多线程模拟实现秒杀抢单
2018/02/07 PHP
javascript编程起步(第二课)
2007/02/27 Javascript
javascript+mapbar实现地图定位
2010/04/09 Javascript
utf-8编码引起js输出中文乱码的解决办法
2010/06/23 Javascript
jquery连缀语法如何实现
2012/11/29 Javascript
JavaScript定时显示广告代码分享
2015/03/02 Javascript
JQuery使用$.ajax和checkbox实现下次不在通知功能
2015/04/16 Javascript
jQuery如何使用自动触发事件trigger
2015/11/29 Javascript
全面解析JavaScript里的循环方法之forEach,for-in,for-of
2020/04/20 Javascript
Javascript 事件冒泡机制详细介绍
2016/10/10 Javascript
JS实现滑动门效果的方法详解
2016/12/19 Javascript
ES6新特性六:promise对象实例详解
2017/04/21 Javascript
vue2利用Bus.js如何实现非父子组件通信详解
2017/08/25 Javascript
Node解决简单重复问题系列之Excel内容的获取
2018/01/02 Javascript
解决Angular.js中使用Swiper插件不能滑动的问题
2018/02/26 Javascript
Vue不能观察到数组length的变化
2018/06/08 Javascript
vue下载excel的实现代码后台用post方法
2019/05/10 Javascript
vue 使用 sortable 实现 el-table 拖拽排序功能
2020/12/26 Vue.js
详解Python中for循环的使用方法
2015/05/14 Python
python实现搜索本地文件信息写入文件的方法
2016/02/22 Python
使用Python对MySQL数据操作
2017/04/06 Python
Python设计模式之工厂模式简单示例
2018/01/09 Python
CSS3实现歌词进度文字颜色填充变化动态效果的思路详解
2020/06/02 HTML / CSS
COACH德国官方网站:纽约现代奢侈品牌,1941年
2018/06/09 全球购物
大学生最常用的自我评价
2013/12/07 职场文书
小学教师管理制度
2014/01/18 职场文书
解决Jenkins集成SonarQube遇到的报错问题
2021/07/15 Java/Android