简单谈谈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 相关文章推荐
getElementByIdx_x js自定义getElementById函数
Jan 24 Javascript
javascript学习笔记(十九) 节点的操作实现代码
Jun 20 Javascript
JavaScript中的运算符种类及其规则介绍
Sep 26 Javascript
无刷新预览所选择的图片示例代码
Apr 02 Javascript
JS实现的点击表头排序功能示例
Mar 27 Javascript
Vue.js 2.0学习教程之从基础到组件详解
Apr 24 Javascript
Vue+Element使用富文本编辑器的示例代码
Aug 14 Javascript
使用jQuery实现页面定时弹出广告效果
Aug 24 jQuery
Angular整合zTree的示例代码
Jan 24 Javascript
js中arguments对象的深入理解
May 14 Javascript
JS面向对象之多选框实现
Jan 17 Javascript
vue3.0实现点击切换验证码(组件)及校验
Nov 18 Vue.js
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调用Webservice实例代码
2011/07/29 PHP
详谈PHP中的密码安全性Password Hashing
2017/02/04 PHP
用PHP去掉文件头的Unicode签名(BOM)方法
2017/06/22 PHP
php注册系统和使用Xajax即时验证用户名是否被占用
2017/08/31 PHP
尽可能写&quot;友好&quot;的&quot;Javascript&quot;代码
2007/01/09 Javascript
JavaScript的eval JSON object问题
2009/11/15 Javascript
js控制frameSet示例
2013/09/10 Javascript
Extjs的FileUploadField文件上传出现了两个上传按钮
2014/04/29 Javascript
用js的document.write输出的广告无阻塞加载的方法
2014/06/05 Javascript
JavaScript数据结构与算法之栈与队列
2016/01/29 Javascript
jQuery AjaxUpload 上传图片代码
2016/02/02 Javascript
Angular2 环境配置详细介绍
2016/09/21 Javascript
关于微信上网页图片点击全屏放大效果
2016/12/19 Javascript
JavaScript截屏功能的实现代码
2017/07/28 Javascript
nodejs 图解express+supervisor+ejs的用法(推荐)
2017/09/08 NodeJs
小程序关于请求同步的总结
2019/05/05 Javascript
Node.js 多进程处理CPU密集任务的实现
2019/05/26 Javascript
vue实现在线预览pdf文件和下载(pdf.js)
2019/11/26 Javascript
微信小程序拖拽排序列表的示例代码
2020/07/08 Javascript
解决vue单页面多个组件嵌套监听浏览器窗口变化问题
2020/07/30 Javascript
[50:12]EG vs Fnatic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
讲解Python中运算符使用时的优先级
2015/05/14 Python
Python实现保证只能运行一个脚本实例
2015/06/24 Python
PyTorch上实现卷积神经网络CNN的方法
2018/04/28 Python
Python实现的读写json文件功能示例
2018/06/05 Python
浅谈pytorch和Numpy的区别以及相互转换方法
2018/07/26 Python
Flask框架模板继承实现方法分析
2019/07/31 Python
python图片指定区域替换img.paste函数的使用
2020/04/09 Python
新版Pycharm中Matplotlib不会弹出独立的显示窗口的问题
2020/06/02 Python
Python中random模块常用方法的使用教程
2020/10/04 Python
CSS3中的content属性使用示例
2015/07/20 HTML / CSS
全球速卖通:AliExpress(国际版淘宝)
2017/09/20 全球购物
面向对象编程是如何提高软件开发水平的
2014/05/06 面试题
幼师专业求职推荐信
2013/11/08 职场文书
表彰会主持词
2014/03/26 职场文书
2016年推广普通话宣传周活动总结
2016/04/06 职场文书