题目:以下两种方式调用函数是,alert的结果是?
    var foo=1;function main(){alert(foo);var foo=2;alert(this.foo);this.foo=3;}main();              //输出undefined,1new main();      //输出undefined,undefined
先了解JavaScript的预编译:

function main(){ };

这种形式是声明一个函数,跟 var 一个变量的机制一样,脚本在解释执行之前会做预编译处理,

var main= function(){ };

这种形式是对一个变量赋值,虽然也做预编译,但仅仅只是给 main事先变量分配一个内存空间,而没有做初始化;
关于声明提升是指:js在解析的时候总是会将var, function这类关键词的声明语句提升至该作用域的最顶部(注意:这里只会提升声明部分)。

  alert(typeof addB);var addB = "variable";function addB() {alert("function addB");}alert(addB);

执行的结果是:function,variable;由此可看出,函数先被预编译处理,而后再是变量;

再了解下作用域链:

js在访问一个变量时会优先在该作用域(访问时的那个作用域)内寻找是否声明过该变量,如果该变量已经存在,则直接使用它的值,否则它会寻找该作用域的‘父作用域/上级作用域’,以此类推,直到找到全局作用域为止。

回到题目上,main函数中执行第一个alert(foo),先寻找foo,发现有定义变量foo,但是在alert之前并未赋值,所以代码等同如下:
    var foo=1;function main(){var foo;alert(foo);foo=2;alert(this.foo);this.foo=3;}main()

此时显而易见,第一个alert(foo)时,他会先在main函数中查找是否有foo变量,没有才回去上层的scope中查找。因为main函数中有声明foo变量,但是alert在他赋值之前,所以返回的是undefined;
第二个alert(this.foo),main()执行时,this指向的是window,所以this.foo是window的全局变量“1”;

关于this指向的问题:

-当函数作为一个对象属性被调用时,this指向的就是他的调用者,即那个对象;
-当函数直接被调用时,他的调用者其实就是window对象;
-当函数作为构造函数被执行时,他的this指向的是构造函数实例化出来的对象;
-我们还可以使用call/apply来改变默认的this指向。

故,执行 new main(); 时,this.foo 为实例化对象实例的属性foo,而在构造函数main中,foo为定义成私有属性,故new main()并不能访问构造函数main的私有属性,所有返回undefined。

下面内容摘自豪情,个人感觉理解起来比较直接

//构造函数//使自己的对象多次复制,同时实例根据设置的访问等级可以访问其内部的属性和方法//当对象被实例化后,构造函数会立即执行它所包含的任何代码function myObject(msg){//特权属性(公有属性)this.myMsg = msg; //只在被实例化后的实例中可调用this.address = '上海';//私有属性var name = '豪情';var age = 29;var that = this;//私有方法function sayName(){alert(that.name);}//特权方法(公有方法)//能被外部公开访问//这个方法每次实例化都要重新构造而prototype是原型共享,所有实例化后,都共同引用同一个this.sayAge = function(){alert(name); //在公有方法中可以访问私有成员}//私有和特权成员在函数的内部,在构造函数创建的每个实例中都会包含同样的私有和特权成员的副本,//因而实例越多占用的内存越多}//公有方法//适用于通过new关键字实例化的该对象的每个实例//向prototype中添加成员将会把新方法添加到构造函数的底层中去myObject.prototype.sayHello = function(){alert('hello everyone!');}//静态属性//适用于对象的特殊实例,就是作为Function对象实例的构造函数本身myObject.name = 'china';//静态方法myObject.alertname = function(){alert(this.name);}//实例化var m1 = new myObject('111');//---- 测试属性 ----////console.log(myObject.name); //china//console.log(m1.name); //undefined, 静态属性不适用于一般实例//console.log(m1.constructor.name); //china, 想访问类的静态属性,先访问该实例的构造函数,然后在访问该类静态属性//console.log(myObject.address); //undefined, myObject中的this指的不是函数本身,而是调用address的对象,而且只能是对象//console.log(m1.address); //上海 此时this指的是实例化后的m1//---- 测试方法 ----////myObject.alertname(); //china,直接调用函数的类方法//m1.alertname(); //FF: m1.alertname is not a function, alertname 是myObject类的方法,和实例对象没有直接关系//m1.constructor.alertname(); //china, 调用该对象构造函数(类函数)的方法(函数)//m1.sayHello(); //hello everyone, myObject类的prototype原型下的方法将会被实例继承//myObject.sayHello(); //myObject.sayHello is not a function,sayHello是原型方法,不是类的方法//---- 测试prototype ----////console.log(m1.prototype); //undefined, 实例对象没有prototype//console.log(myObject.prototype); //Object //alert(myObject.prototype.constructor); //console.log返回myObject(msg),此时alert()更清楚,相当于myObject//console.log(myObject.prototype.constructor.name); //china, 相当于myObject.name; 
相关案例:
a = 1    // 1
this.a   // 1
window.a // 1
delete a // truevar b = 2// 2
this.b   // 2
window.b // 2
delete b // false

从例子看以看出,未通过var声明的变量a和通过var声明的变量b,都可以通过this和window访问到,区别是一个可以被delete,一个不可以,下面分析下:
因为(在全局下)通过var 声明的变量是全局变量,而未通过var声明的变量是附在this,也就是window上的属性,而属性是可以被删除的。
在浏览器中,所以的变量都是存在于window下的,所以可以被window访问到;
而this是指向window的一个引用,未通过var声明的变量通过附在this上,达到可以全局访问的效果。

转载于:https://www.cnblogs.com/wjx91/p/5575710.html

2016阿里前端笔试题学习相关推荐

  1. 前端笔试题面试题记录(上)

    前言 过完元宵,就到上海找了波工作,现在已经入职好了,蹭波热点,写一波面试记录,内容包含笔试题和面试题,还有一些没有写进来,准备再开一篇,许久没写了,写的确实有些慢.如果喜欢的话可以点波赞,或者关注一 ...

  2. 前端笔试题【1】--从字符串的第二个字符开始对数组进行排序

    前一段时间做过一个阿里的前端笔试题:从字符串的第二个字符开始对数组进行排序.当时没想到简单的方法,这几天看书才发现sort()还可以自定义一个比较函数,郁闷啊啊啊~~ 看来基础还是不够扎实啊, 赶紧记 ...

  3. html5 笔试题 选择题,2019拼多多前端笔试题

    选择.填空题: 1.IP地址,子网掩码的计算 2.Internet网络层重要协议 3.http请求方法 4.HTML中a标签的伪类 5.alert(undefined==null)的输出结果 6.ht ...

  4. 也许你需要点实用的-Web前端笔试题

    之前发的一篇博客里没有附上答案,现在有空整理了下发出来,希望能帮助到正在找工作的你,还是那句话:技术只有自己真正理解了才是自己的东西,共勉. Web前端笔试题 Html+css 1.对WEB标准以及w ...

  5. 前端笔试题小结(一)

    前端笔试题小结(一) 2020-03-13 题目一: 将一个js数组去重. 样例: 输入:[ 1, "apple", 3, "a", 3, 1, 5, 6, & ...

  6. 前端笔试题面试题记录(下)

    前言 接上篇前端笔试题面试题记录(上).趁清明小长假,把上篇剩下的部分也写一下,因为最近比较忙这篇已经拖了很久了.现在刚刚开始银四了,应该还是有些小伙伴在找工作,时间还不算太晚,希望本篇可以帮到这些小 ...

  7. 名企笔试:京东 2016 算法工程师笔试题(登楼梯)

    名企笔试:京东 2016 算法工程师笔试题(登楼梯) 2017-02-04 算法爱好者 有一段楼梯台阶有 15 级台阶,以小明的脚力一步最多只能跨 3 级,请问小明登上这段楼梯,有多少种不同的走法? ...

  8. 携程2016研发工程师笔试题

    携程2016研发工程师笔试题 2015/12/7 14:56(网上收集整理的,参考答案在后面,若有错误请大神指出) 1. 内存空间被分成不同区域,其中用函数 void*malloc(unsigned ...

  9. 分苹果(2016京东招聘笔试题)

    笔试题:分苹果(2016京东招聘笔试题) 题目: 果园里有一堆苹果,一共n头(n大于1小于9)熊来分,第一头为小东,它把苹果均分n份后,多出了一个,它扔掉了这一个,拿走了自己的一份苹果,接着第二头熊重 ...

最新文章

  1. Mac下使用svn命令
  2. 阿里云POLARDB荣膺2019中国数据库年度最佳创新产品
  3. WebAssembly的Qt
  4. txt文本改html没有用,编辑html格式文本可改成txt格式(可以替换或更换某文本)新手...
  5. NET问答: 如何从 string 中挖出所有的 number ?
  6. 线程自动退出_C++基础 多线程笔记(一)
  7. python redis模块connectionerror_ConnectionError:Error 2连接到Python/Django Redis中的unix套接字...
  8. 为什么要学python语言、学完有什么好处_学编程为什么首选Python?学完Python的优势有哪些?...
  9. java - 判断任意一天是这年的第几天
  10. 10 WM配置-主数据-定义仓位类型(Bin Type)
  11. mysql group b_mysql报错之5.7版本的 group by mysql不能使用group by
  12. 20200701:力扣194周周赛上
  13. java list打乱排序_JAVA Collections.shuffle打乱列表
  14. mysql读会产生事务吗_来谈谈MySQL事务及事务引发的问题
  15. 利用并查集+贪心解决 Hdu1232
  16. 传智播客java测试题_传智播客java笔试题
  17. 苹果清除感染 XCodeGhost 的应用
  18. 锐捷服务器端口映射教程,锐捷路由器端口映射,路由器端口映射
  19. 贝叶斯公式的最通俗解释
  20. 联想Lenovo——何去何从

热门文章

  1. 敏捷个人俱乐部2012年2月线下活动:活出我的最好生活
  2. Android 基本面试题
  3. Nosql数据一致性技术概要
  4. Windows Shell 学习 3
  5. Android开发之大位图二次采样压缩处理(源代码分享)
  6. 动态绑定与继承:不得不去想细节
  7. Android offsetTopAndBottom 和 setTranslationY 的作用 和区别
  8. Linux【命令】修改文件内容
  9. Java并发:明白Synchronized实现原理,锁什么?
  10. 第十六周程序阅读(1)