在看《高级程序设计》(我的红宝书) P.183页时遇到下面一个问题

var name = "77";
var obj = {
name: "88",
getName: function () {
return this.name;
}
};
(obj.getName = obj.getName)(); //返回全局变量 77

这个问题看起来好像有点奇葩,其实它可以从以下两个方面切入。

一、  在于obj.getName = obj.getName这个赋值的问题。我们可以先看一下规范对 a = b; 的解释,它其实发生了四步操作:

  1. 计算表达式a,得到a的地址refa;
  2. 计算表达式b, 得到b的值valueb;
  3. 将valueb赋给refa。
  4. 返回valueb

从上面的赋值过程中我们可以看到 obj.getName = obj.getName 会返回第二个 obj.getName 所指向的函数表达式。

于是就可以将(obj.getName = obj.getName)()视作全局函数。这个问题便可以看做

var name = "77";
var obj = {
name: "88",
getName: function () {
return this.name;
}
};
var fn = obj.getName;
fn(); //返回全局变量 77

二、this的值基于调用的位置

this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用位置(也就是函数的调用方式)。S的解释器是怎么知道this到底指向谁的(排除掉call和apply改变this)?重点就在于这个  . 号,有了  . ,他就知道是谁在调用,自然就会把this指向这个调用者。而上面那种写法,就直接调用了一个函数,没有  .,他自然不知道this是谁,它在全局中被调用,所以默认就是window了。

所以在全局中调用函数的时候 this 指向window,所以他会返回 77,而不是88.

this在方法赋值过程中无法保持(隐式丢失)的更多相关文章

  1. 学好Spark/Kafka必须要掌握的Scala技术点(三)高阶函数、方法、柯里化、隐式转换

    5. 高阶函数 Scala中的高阶函数包含:作为值的函数.匿名函数.闭包.柯里化等,可以把函数作为参数传递给方法或函数. 5.1 作为值的函数 定义函数时格式: val 变量名 = (输入参数类型和个 ...

  2. 【C++】赋值过程中类型转换

    注意:以下内容摘自文献[1],修改了部分内容. 1.赋值过程中的类型转换 如果赋值运算符两侧的类型不一致,但都是数值型或字符型时,在赋值时自动进行类型转换. (1) 将浮点型数据(包括单.双精度)赋给 ...

  3. F#中的自定义隐式转换

    我们知道隐式变换在可控情况下会使代码变得简洁.熟悉C#的都知道C#中可以自定义隐式变换,例如 public class A { private int data; public static impl ...

  4. SQL Server中提前找到隐式转换提升性能的办法

        http://www.cnblogs.com/shanksgao/p/4254942.html 高兄这篇文章很好的谈论了由于数据隐式转换造成执行计划不准确,从而造成了死锁.那如果在事情出现之前 ...

  5. Android中显示和隐式Intent的使用

    显示启动activity                                                                                         ...

  6. Spark Mllib里的协调过滤的概念和实现步骤、LS、ALS的原理、ALS算法优化过程的推导、隐式反馈和ALS-WR算法

    不多说,直接上干货! 常见的推荐算法 1.基于关系规则的推荐 2.基于内容的推荐 3.人口统计式的推荐 4.协调过滤式的推荐 (广泛采用) 协调过滤的概念 在现今的推荐技术和算法中,最被大家广泛认可和 ...

  7. js中的一些隐式转换和总结

    js中的不同的数据类型之间的比较转换规则如下: 1. 对象和布尔值比较 对象和布尔值进行比较时,对象先转换为字符串,然后再转换为数字,布尔值直接转换为数字 [] == true; //false [] ...

  8. js中的数据类型隐式转换的三种情况

    js的数据类型隐式转换主要分为三种情况: 1. 转换为boolean类型 2. 转换为number类型 3. 转换为string类型 转换为boolean类型 数据在 逻辑判断 和 逻辑运算 之中会隐 ...

  9. 从字节码看java中 this 的隐式传参

    从字节码看java中 this 隐式传参具体体现(和python中的self如出一辙,但是比python中藏得更深),也发现了 static 与 非 static 方法的区别所在! static与非s ...

随机推荐

  1. 华为AI应用创新大赛即将开启!公开课已备好!

    为鼓励开发者创新,挖掘前沿创新能力的应用及服务,帮开发者打造爆款应用的同时丰富终端消费者的用户体验,由设立10亿激励基金耀星计划扶持的华为创新竞赛平台即将开启. 竞赛平台将滚动推出AI.HAG.AR. ...

  2. js jquery 插件

    $(function(){ (function($, document, undefiend){ $.fn.pagination = function(options){ var $this = $( ...

  3. PageHelper

    https://pagehelper.github.io/ Mybatis分页插件PageHelper简单使用 SpringBoot之分页PageHelper

  4. Swift 学习笔记 (属性)

    属性可以将值与特定的类 结构体 或者枚举联系起来. 存储属性会存储常量或者变量作为实例的一部分.反之计算属性会计算(而不是存储值)值. 计算属性可以由类 结构体 和枚举定义.存储属性只能由类和结构体定 ...

  5. HTML 学习笔记 JQuery(事件)

    加载DOM 以浏览器加载文档为例,在页面加载完毕后,浏览器会通过JavaScript为DOM元素添加事件.在常规的JavaScript中,通常使用window.onload方法,在JQuery中通常使 ...

  6. 在tomcat下直接访问Html报错,说找不到资源(404)

    今天由于工作需要,想把一个html直接放到tomcat(干净的tomcat,没有做过任何修改.)下进行访问,然后根据经验就直接在webapps下创建了个文件夹test,然后把需要的test.html拷 ...

  7. Java图像处理最快技术:ImageJ 学习第一篇

    ImageJ是世界上最快的纯Java的图像处理程序. 它能够过滤一个2048x2048的图像在0.1秒内(*). 这是每秒40万像素!ImageJ的扩展通过使用内置的文本编辑器和Java编译器的Ima ...

  8. Nginx Cache中$request_filename(转)

    对于Nginx的$request_filename变量指的就是请求的资源路径.在原先 OpenCDN节点端配置里面是这样的. location ~ .*\.(png|html|htm|ico|jpg| ...

  9. JavaScript学习笔记(持续更新)

    函数有“定义式”和“变量式”两种写法的区别 函数有“定义式”和“变量式”两种写法,两者基本区别不大.主要区别在于,如果在同一个代码块(Script标签对)定义两个同名的函数,浏览器在预编译代码时,使用 ...

  10. web项目中从不同的路径读取文件

    项目中的配置文件可以放在classpath下,webapp下获取其他任何一个指定的绝对地址,读取这些文件就从这三个地方去找.主要代码如下: private List<String> get ...