一道面试题让你与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 这个同步 ...
随机推荐
- day 51 随机验证码, 验证登陆 ,以及 装饰器在函数中的应用
前端很好的session 的例子 (随机验证码登陆) https://github.com/Endless-Clould/qianduan 参考: 验证码登录 https://www.cnblogs. ...
- 无apk,怎么获取app的activity
在做app自动化测试之前,有个前提条件,就是要获取当前app的包名和当前活动的activity.如果有提供了.apk,就可以直接通过adb命令获取到包名和欢迎页面:有种软件是手机自带的的,我们不知道a ...
- 剑指offer四十二之和为S的两个数字
一.题目 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 二.思路 数列满足递增,设两个头尾两个指针i和j,若ai + ...
- (转)MySQL字段类型详解
MySQL字段类型详解 原文:http://www.cnblogs.com/100thMountain/p/4692842.html MySQL支持大量的列类型,它可以被分为3类:数字类型.日期和时间 ...
- Spring Security构建Rest服务-0801-短信验证码发送
实现短信验证码登录 开发短信验证码接口 校验短信验证码并登录 短信验证码和图片验证码开发思路类似: 1,我们访问一个controller 2,在controller里调用短信验证码生成接口生成验证码 ...
- web测试总结—用户体验
一.什么是用户体验 用户体验,英文叫做user experience,缩写为UE,或者UX.一个较常见的定义是“指用户访问一个网站或者使用一个产品时的全部体验.他们的印象和感觉,是否成功,是否享受,是 ...
- 全连接层(FC)与全局平均池化层(GAP)
在卷积神经网络的最后,往往会出现一两层全连接层,全连接一般会把卷积输出的二维特征图转化成一维的一个向量,全连接层的每一个节点都与上一层每个节点连接,是把前一层的输出特征都综合起来,所以该层的权值参数是 ...
- R语言常用包分类总结
常用包: ——数据处理:lubridata ,plyr ,reshape2,stringr,formatR,mcmc: ——机器学习:nnet,rpart,tree,party,lars,boost, ...
- 16-hadoop-mapreduce简介
mapreduce是hadoop的核心组件, 设计理念是移动计算而不是移动数据, mapreduce的思想是'分而治之', 将复杂的任务分解成几个简单的任务去执行 1, 数据和计算规模大大减少 2, ...
- 13-hadoop-入门程序
通过之前的操作, http://www.cnblogs.com/wenbronk/p/6636926.html http://www.cnblogs.com/wenbronk/p/6659481.ht ...