一道面试题让你与JS更近一步
这是一道面试题, 请先思考,在看讲解 :)
var param = 1; function main()
{
console.log(param);
var param = 2;
console.log(this.param);
this.param = 3;
} //下面两条语句分别会在控制台打印什么?
main();
var m = new main();
讲解如下:
1. main() , 打印的结果为: undefined , 1
a. > 来看第一个打印的值为什么是 undefined。 在js中,方法和变量的声明都是会提前的。也就是说不管你在何处声明的方法或者变量,在js解析时,都会将其提前,具体看代码
demo(); //此处能正常弹出 similar function demo()
{
alert("similar");
}
按照js的语句执行顺序,应该是从上自下依次执行的。 也就是说会先执行demo(), 然而这个时候demo()还没有声明,并不存在,应该报错才对,为什么还能正常弹出similar呢?这就前面说的方法声明在js解析时会提前。所以上面的代码,经过解析之后,就相当于
function demo()
{
alert("similar");
} demo(); //此处能正常弹出 similar
所以才会正常弹出 similar。 那么对于变量的声明也是一样的,会提前。 我们上面的代码,经过解析之后实际上等同于下面的代码
var param; //声明提前
param = 1; function main()
{
var param; //声明提前
console.log(param); //因为此时 param 只是进行了声明,并未赋值,所以 打印的是 undefined
param = 2;
console.log(this.param);
this.param = 3;
}
这里你或许会感到疑惑。我们在main()方法外面不是已经赋值为1了吗? 这是因为,我们在main()方法里面也定义了一个同名的 param。 就近原则,js会先查找自己有没有这个变量,如果有,就用自己的,如果没有就向上级查找,上级还是没有就到上上级去查找,如此循环,在哪找到,就在哪停止。如果全都没有,就返回undefined。 【这里涉及到一个知识点: js作用域链及变量查找】
b. > 现在我们再来看看第二打印的值为什么是1。 我将代码再做一次等价转换,这样或许大家就更容易明白缘由了,转换后代码如下
window.param = 1; //全局变量 param // 全局方法 main()
window.main = function () {
console.log(param);
var param = 2;
console.log(this.param); //此时的this指代的就是 window, 因此 this.param = window.param = 1
this.param = 3;
}
//调用全局方法main()
window.main();
看到这里,大家是否有些明白了呢?因为 main() 方法和 main() 方法外面的 param 都是定义在最外层的(没有包裹在其他对象里面),因此他们都是全局对象window下的成员。 当我们调用 main() 方法时, 实际上就是调用的 window.main(); 而通过这样的方式调用时, this 指代的就是全局对象 window。 所以第二个打印的值为 1。【这里涉及到一个知识点:js中让人迷糊的this】
2. var m = new main(), 打印的结果为: undefined, undefined
a. > 第一个打印的值为 undefined 的原因和上面的原因是一样的,都是因为变量声明提前导致的。
b. > 那么第二个打印的值也为 undefined 的原因是什么呢? Js也是支持面向对象式编程的语言,然而js中却没有类的概念,而是使用基于原型(prototype)的继承。 因此呢,js中的构造函数也很特别,一般情况下它和普通方法没什么区别,只有通过 new 关键字来调用的时候才能体现出其作为构造函数的功能。 而此处正是把 main() 和 new 关键字一起使用,说明此时的main()是一个构造函数。而构造函数中的 this 指代的就是新创建的对象,那么也就是 m 。
var param = 1; function main()
{
var param; //声明提前
console.log(param); //因为此时 param 只是进行了声明,并未赋值,所以 打印的是 undefined
param = 2;
console.log(this.param); //构造函数中的this指代的是新创建的对象,我们这里新创建的对象是 m , 所以 this.param = m.param , 而此时 this.param 尚未赋值,所以打印的是 undefined (此处我自己也有一个疑问: 构造函数中的属性的声明会提前吗?也就是 this.param 的声明会提前吗? 求解)
this.param = 3;
} var m = new main();
说到底这里还是一个关于 js 中 this 的理解的问题,掌握了this , 此问题就很好理解了。现在都知道各中缘由了,是不是有种豁然开朗的感觉,哈哈...
一道面试题让你与JS更近一步的更多相关文章
- 一道面试题与Java位操作 和 BitSet 库的使用
前一段时间在网上看到这样一道面试题: 有个老的手机短信程序,由于当时的手机CPU,内存都很烂.所以这个短信程序只能记住256条短信,多了就删了. 每个短信有个唯一的ID,在0到255之间.当然用户可能 ...
- 关于一道面试题,使用C#实现字符串反转算法
关于一道面试题,使用C#实现字符串反转算法. 题目见http://student.csdn.net/space.php?do=question&ac=detail&qid=490 详细 ...
- 一道笔试题和UML思想 ~
一句软件工程界的名言,让我想起了一个和一道笔试题有关的故事.希望更多的人了解 UML 背后的思想比他的语法更重要,是笔者写作本文的一点小愿望. 一.从一句软件工程名言说起 对很多事情的处理上,东西方都 ...
- 【死磕JVM】一道面试题引发的“栈帧”!!!
前言 最近小农的朋友--小勇在找工作,开年来金三银四,都想跳一跳,找个踏(gao)实(xin)点的工作,这不小勇也去面试了,不得不说,现在面试,各种底层各种原理,层出不穷,小勇就遇上了这么一道面试题, ...
- PHP递归创建多级目录(一道面试题的解题过程)
今天看到一道面试题,要写出一个可以创建多级目录的函数: 我的第一个感觉就是用递归创建,具体思路如下: function Directory($dir){ if(is_dir($dir) || @mkd ...
- 关于Java类加载双亲委派机制的思考(附一道面试题)
预定义类加载器和双亲委派机制 JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib下面 ...
- 一道面试题比较synchronized和读写锁
一.科普定义 这篇博文的两个主角“synchronized”和“读写锁” 1)synchronized 这个同步关键字相信大家都用得比较多,在上一篇“多个线程之间共享数据的方式”中也详细列举他的应用, ...
- 一道面试题:按照其描述要求用java语言实现快速排序
回来想了想,写出了如下的程序: /** * 一道面试题,按照其描述要求进行快速排序(英文的,希望理解是对的..) * 要求:和一般的快速排序算法不同的是,它不是依次交换pivot和左右元素节点(交换2 ...
- <转>一道面试题比较synchronized和读写锁
一.科普定义(原文:http://903497571.iteye.com/blog/1874752) 这篇博文的两个主角“synchronized”和“读写锁” 1)synchronized 这个同步 ...
随机推荐
- 奇怪的Java题:为什么1000 == 1000返回为False,而100 == 100会返回为True?
如果你运行如下代码: 1 2 3 4 Integer a = 1000, b = 1000; System.out.println(a == b);//1 Integer c = 100, d = ...
- iOS开发总结--三方平台开发之分享
1.前言 在公司参与了多个应用三方平台的开发,涉及微信.微博.QQ.Facebook.meetup等,总结一下一般的接入三方平台SDK方法. 2.接入三方SDK 任何应用要接入三方平台,都需要在该平台 ...
- AppScan安全测试入门操作
appscan:可以对网站等 Web 应用进行自动化的应用安全扫描和测试,也就是经常说的安全测试 工作原理:是通过对web应用进行安全攻击来检查网站是否存在漏洞. 初步了解到的 创建新的扫描-> ...
- vsto之一简介(系列文章为转载)
该系列文章转载自 http://bbs.51cto.com/thread-1017338-1.html 参考资料 http://www.excelpx.com/thread-184209-1-1 ...
- CentOS 安装Scrapy
本文python版本是python3.5.3,关于升级python和安装pip请到:http://www.cnblogs.com/technologylife/p/6242115.html 安装相关包 ...
- Observer观察者设计模式
Observer设计模式主要包括以下两种对象: (1)被观察对象:Subject,它往往包含其他对象感兴趣的东西,上面例子中热水器中就是Subject(被监视对象); (2)观察对象:Observer ...
- web测试总结—用户体验
一.什么是用户体验 用户体验,英文叫做user experience,缩写为UE,或者UX.一个较常见的定义是“指用户访问一个网站或者使用一个产品时的全部体验.他们的印象和感觉,是否成功,是否享受,是 ...
- Python -- 网络编程 -- 认识Python3的urllib库
Python3的urllib包含5个模块 urllib error parse request response robotparser 各个模块的主要成员: error ['ContentTooSh ...
- #pragma的一些用法
1.#pragma message message 参数:Message参数能够在编译信息输出窗口输出相应的信息,这对于源代码的信息控制特别重要,其使用方法为: #pragma message(&qu ...
- lintcode-->哈希函数
在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假设任何字符串都是基 ...