请说明要输出正确的myName的值要如何修改程序?并解释原因
foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(){
alert(this.myName);
}
foo.prototype.bar = function(){
setTimeout(this.sayHello, );
}
var f = new foo;
f.bar();

先跟踪一下函数的执行。

全局环境下,声明一个变量,实例化foo赋值给f,函数未执行。打印f,结果是:

很显然,f就是一个foo的副本,它是一个对象,副本内部的函数就是该对象的方法,可以点式调用。foo是函数不可以直接作为对象调用内部方法。

console.log(typeof f); //object
console.log(typeof foo);  //function

tips:函数foo内部声明的属性或方法前加this目的在于保护变量同时可以被实例化的对象访问,如果直接声明私有变量,无法实例化后使用,而若成为全局变量又可能造成污染。比如去掉setTimeout前的this,那么sayHello变成了全局变量,而若全局中未声明这个函数,就会造成错误。

console.log(f.name);//Foo function

对象f调用bar之后,被赋值的函数执行,this指向这个对象,然后setTimeout开始执行,指向window,f的方法sayHello在5s后被调起,此时它处在windows环境中,因此alert(this.myName)会尝试去window环境获取这个值。如下:

var myName = "江太公";
//or this.myName = "江太公";
function sayHello(){alert("江太公");}
foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(){
alert(this.myName);
}
foo.prototype.bar = function(){
setTimeout(this.sayHello, 5000);
}
var f = new foo;
console.log(f);
f.bar();
console.log(f.bar);
console.log(foo.bar);
console.log(typeof f);
console.log(typeof foo);
// console.log(f.myName);

结果弹出:江太公。证实我的想法。

ok,整个执行流程很简单,但中间的this转换可能让人困惑。下面给出这道题的4种解决方案。

方案一:用bind对this进行转向。

foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(){
alert(this.myName);
}
foo.prototype.bar = function(){
setTimeout(this.sayHello.bind(this), 5000);
}
var f = new foo;
f.bar();

方案二:用call/apply进行转向。

foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(){
alert(this.myName);
}
foo.prototype.bar = function(){
setTimeout(this.sayHello.apply(this), 5000);
}
var f = new foo;
f.bar();

方案三:用that进行hack。

foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(that){
alert(that.myName);
}
foo.prototype.bar = function(){
var that = this;
setTimeout(function(){that.sayHello(that);}, 5000);
}
var f = new foo;
f.bar();

方案四:使用箭头函数。

foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(){
alert(this.myName);
}
foo.prototype.bar = function(){
setTimeout(()=>{this.sayHello()}, 5000);
}
var f = new foo;
f.bar();

或者:

foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = ()=>{alert(this.myName)};
foo.prototype.bar = function(){
setTimeout(this.sayHello, );
}
var f = new foo;
f.bar()

方法五:还有一种特特简单的办法,将构造函数的this也转向到全局。

foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(){
alert(this.myName);
}
foo.prototype.bar = function(){
setTimeout(this.sayHello, );
}
var f = new foo;
foo();
f.bar()

发现其他途径烦请告我一声,谢谢。

知乎一道前端面试题详解,关于this的使用的更多相关文章

  1. 一道前端面试题:定义一个方法将string的每个字符串间加个空格返回,调用的方式'hello world'.spacify();

    偶然在群里看到了这道题:定义一个方法将string的每个字符串间加个空格返回,调用的方式'hello world'.spacify(); 这道题主要是对JavaScript对象原型的考察.

  2. 金三银四求职季,前端面试题小梳理(HTML、CSS、JS)

    好久没写学习记录,最近太多事,又到一年求职季,都说金三银四求职季,自己也做一下最近学习的一些前端面试题梳理,还是个小白,写的不对请指正,不胜感激. HTML篇 html语义化 用语义化的代码标签书写, ...

  3. 常见前端面试题之HTML/CSS部分

    转自http://www.cnblogs.com/jscode/archive/2012/07/10/2583856.html Doctype是什么?如何触发严格模式与混杂模式模式?区分它们有何意义? ...

  4. 【重点--web前端面试题总结】

    前端面试题总结 HTML&CSS: 对Web标准的理解.浏览器内核差异.兼容性.hack.CSS基本功:布局.盒子模型.选择器优先级及使用.HTML5.CSS3.移动端适应. JavaScri ...

  5. 前端周报:前端面试题及答案总结;JavaScript参数传递的深入理解

    1.2017前端面试题及答案总结 |掘金技术征文 "金三银四,金九银十",用来形容求职最好的几个月.但是随着行业的饱和,初中级前端er就业形势不容乐观. 行业状态不可控,我们能做的 ...

  6. web前端面试题HTML/CSS部分

    web前端面试题HTML/CSS部分 前端页面有哪三层构成,分别是什么?作用是什么? 1.结构层:由 HTML 或 XHTML 之类的标记语言负责创建,仅负责语义的表达.解决了页面“内容是什么”的问题 ...

  7. 好程序员分享Web前端面试题汇总JS篇之跨域问题

    为什么80%的码农都做不了架构师?>>>   好程序员分享Web前端面试题汇总JS篇之跨域问题,接着上一篇文章我们继续来探讨web前端面试必备面试题. 跨域解决方案 1. 通过jso ...

  8. 【web前端面试题整理02】前端面试题第二弹袭来,接招!

    前言 今天本来准备先了解下node.js的,但是,看看我们一个小时前与一个小时后的差距: 既然如此,我们继续来搜集我们的前端面试题大业吧!!! 特别感谢玉面小肥鱼提供哟,@玉面小飞鱼 题目一览 Jav ...

  9. 各大互联网公司前端面试题(js)

    对于巩固复习js更是大有裨益.    初级Javascript: 1.JavaScript是一门什么样的语言,它有哪些特点? 没有标准答案. 2.JavaScript的数据类型都有什么? 基本数据类型 ...

随机推荐

  1. java中关键字this的使用

    在团队代码中看到对于当前类中的方法,使用了this关键字.经过测试发现,在此种情况下,this关键字的使用可有可无.因此,对java中this的使用做下总结: package testTHIS; pu ...

  2. linux使用wkhtmltopdf报错error while loading shared libraries:

    官网提示 linux需要这些动态库.depends on: zlib, fontconfig, freetype, X11 libs (libX11, libXext, libXrender) 在li ...

  3. arcgis engine 中出现的内存堆栈溢出问题。

    两种解决方案: 1.循环加载mxd文档的时候出现的堆栈溢出,解决办法是每次循环结束时清空FeatureLayer,感觉并不好,但是确实可以实现功能. 2.循环调取featureclass的search ...

  4. 使用rsync同步目录

    本文描述了linux下使用rsync单向同步两个机器目录的问题. 使用rsync同步后可以保持目录的一致性(含删除操作). 数据同步方式 从主机拉数据 备机上启动的流程 同步命令: rsync -av ...

  5. SQL Server 如何通过SQL语句定位SSRS中的具体报表

    在一些IT技术人员的推广.简单培训后,公司很多部门都有一些非IT技术人员参与开发各自需求的Reporting Service报表.原因很简单,罗列出来的原因大概有这样一些: IT部门的考量: 1:IT ...

  6. (八)map,filter,flatMap算子-Java&Python版Spark

    map,filter,flatMap算子 视频教程: 1.优酷 2.YouTube 1.map map是将源JavaRDD的一个一个元素的传入call方法,并经过算法后一个一个的返回从而生成一个新的J ...

  7. tcpdump、nc网络工具使用

    tcpdump: 网络嗅探器 nc: nmap: 端口扫描 混杂模式(promisc) C设置为监控,当A和B通信,C是无法探测到数据的,除非有交换机的权限,将全网端口的数据通信都发送副本到C的端口上 ...

  8. EZchip将推全球首款100核64位ARM A-53芯片

    EZchip将推全球首款100核64位ARM A-53芯片 2015-02-25 16:32:03   来源:互联网    关键字: 将推  全球  64位  arm EZchip日前表示,将准备开发 ...

  9. Ural 1225. Flags 斐波那契DP

    1225. Flags Time limit: 1.0 secondMemory limit: 64 MB On the Day of the Flag of Russia a shop-owner ...

  10. Java程序设计之打印100~999的水仙花数

    package printDaffodilNumber; /* * 题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身 ...