关于JS两道有意思的题--作用域与提升

来源:互联网 发布:淘宝评价推荐排序 编辑:程序博客网 时间:2024/06/03 17:53

  第二道题是关于作用域和提升的。

  你应该知道声明都是会被提升的,即var声明跟function声明都会被提升到顶部。你也应该知道有两个操作,声明跟赋值,先声明再赋值。(不知道的话,就得好好在复习一下基础了。)

  基本流程:

var a = 2;

首先var a声明一个a变量,初始化为undefined,提升到顶部,就像

var a;a = 2;

两者是一个意思。然后再对a进行赋值。这有个过程

引擎:作用域,你见过a吗?

作用域:见过,编译器刚声明过这个a变量,拿去用吧!

引擎:好嘞,我给它赋值下。

你还得知道的是,函数优先提升。

var a = 2;function a(){console.log(1);}a//2
函数声明被优先声明到顶部,然后被变量声明覆盖!

好了,接下来看这道题

function Foo() {    getName = function () {     console.log('1');    };    return this;}Foo.getName = function () {console.log('2');};Foo.prototype.getName = function () { console.log('3');};var getName = function () { console.log('4');};function getName() { console.log(5);}Foo.getName();  getName();Foo().getName(); getName();  new Foo.getName(); new Foo().getName();   new new Foo().getName();
首先我们可以看到,被提升的有函数声明Foo(),Foo.getName,Foo.prototype.getName,getName,函数声明getname()。

注意这里只是声明,没有赋值,只是让引擎能找到这些东西。

Foo.getName()引擎问作用域有这个吗?作用域回答有!然后就运行函数,Foo.getName(),输出2。

同理,getName()输出4;

Foo().getName()运行的时候在Foo()作用域中没有getName这个的声明,所以当引擎对getName进行赋值操作时,发现没有这个变量存在,没有是吗?没有就给你声明一个嘛,就立刻声明一个getName的全局变量(注意,覆盖了原先的全局变量getName)。这里输出1。

所以再次调用getName()的时候,它已经被Foo中的那个getName覆盖了,也输出1。

后面三题,我看到的时候奇怪了。虽然我知道new声明,但我之前接触的都是new 一个构造函数,这种new 一个“属性”的我还是第一次见。所以它到底是new 了个什么东西,我都搞不明白,还好原博主贴了张运算符优先级表(如下)点击内容或者外部自动关闭图片预览


所以上面三个其实就是

new (Foo.getName)();

(new Foo()).getName();

new ((new Foo()).getName)();

第一个就是new 了个Foo.getName函数,所以输出的还是2;

第二个就是new了个Foo()然后调用getName方法,注意这里new后新对象是没有getName方法的,所以它要跟着原型链去找getName方法,就是调用Foo.prototype.getName,所以输出3;

第三个就是对第二个又new了一次,还是输出3。




原创粉丝点击