简单谈谈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 源码分析笔记(5) jQuery.support
Jun 19 Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
Sep 14 Javascript
js 输出内容到新窗口具体实现代码
May 31 Javascript
纯js代码实现未知宽高的元素在指定元素中垂直水平居中显示
Sep 12 Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
Sep 21 Javascript
js判断文件格式及大小的简单实例(必看)
Oct 11 Javascript
Vue中定义全局变量与常量的各种方式详解
Aug 23 Javascript
浅谈Vue SSR 的 Cookies 问题
Nov 20 Javascript
Vue瀑布流插件的使用示例
Sep 19 Javascript
解决cordova+vue 项目打包成APK应用遇到的问题
May 10 Javascript
vue-test-utils初使用详解
May 23 Javascript
vue中 this.$set的用法详解
Sep 06 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与XML的PDF文档生成技术
2006/10/09 PHP
如何在WIN2K下安装PHP4.04
2006/10/09 PHP
PHP中其实也可以用方法链
2011/11/10 PHP
js 无提示关闭浏览器页面的代码
2010/03/09 Javascript
jQuery拖拽 &amp; 弹出层 介绍与示例
2013/12/27 Javascript
jQuery+ajax中getJSON() 用法实例
2014/12/22 Javascript
jQuery 获取跨域XML(RSS)数据的相关总结分析
2016/05/18 Javascript
javascript中JSON.parse()与eval()解析json的区别
2016/05/19 Javascript
JS简单测试循环运行时间的方法
2016/09/04 Javascript
全面解析vue中的数据双向绑定
2017/05/10 Javascript
vue做网页开场视频的实例代码
2017/10/20 Javascript
使用ngrok+express解决本地环境中微信接口调试问题
2018/02/26 Javascript
详解使用 Node.js 开发简单的脚手架工具
2018/06/08 Javascript
Angularjs实现数组随机排序的方法
2018/10/02 Javascript
ES6 Object方法扩展的应用实例分析
2019/06/25 Javascript
JS实现商品橱窗特效
2020/01/09 Javascript
JS函数参数的传递与同名参数实例分析
2020/03/16 Javascript
用Python程序抓取网页的HTML信息的一个小实例
2015/05/02 Python
在python中画正态分布图像的实例
2019/07/08 Python
基于django ManyToMany 使用的注意事项详解
2019/08/09 Python
tensorflow多维张量计算实例
2020/02/11 Python
CSS3 边框效果
2019/11/04 HTML / CSS
HTML5移动端开发遇见的东西
2019/10/11 HTML / CSS
RIP版本1跟版本2的区别
2013/12/30 面试题
什么叫做SQL注入,如何防止
2016/10/04 面试题
简单叙述一下MYSQL的优化
2016/05/09 面试题
Java中采用什么结构来捕获、处理异常?各子句的顺序、功能如何
2013/10/07 面试题
法人代表授权委托书
2014/04/08 职场文书
办公室主任竞聘演讲稿
2014/05/15 职场文书
党员评议个人总结
2014/10/20 职场文书
务虚会发言材料
2014/12/25 职场文书
幼儿园工作总结2015
2015/04/01 职场文书
驻村工作简报
2015/07/20 职场文书
导游词之吉林吉塔
2019/11/11 职场文书
html2 canvas svg不能识别的解决方案
2021/06/03 HTML / CSS
Win Server2016远程桌面如何允许多用户同时登录
2022/06/10 Servers