zoukankan      html  css  js  c++  java
  • web前端经典小题

    1.此题涉及的知识点众多,包括变量定义提升、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性及原型属性优先级等等。
    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.getName();//2

    getName();//4

    Foo().getName();//1

    getName();//1

    new Foo.getName();//2

    new Foo().getName();//3

    new new Foo().getName();//3

    解析:先看此题,1.首先创建了一个Foo的函数,2.之后又为Foo创建了一个叫getName的静态属性存储了一个匿名函数,3.之后为Foo的原型创建了一个名叫getName的匿名函数。4.之后又通过函数变量表达式创建了一个getName的函数,5.最后再声明一个叫getName函。

    第一问:自然是访问Foo上的静态属性,是2.

    第二问:此处有两个坑,一是变量声明提升,二是函数表达式

    以上问题代码可以等价于:

    function Foo() {
    getName = function () { console.log(1) };
    return this;
    }
    function getName() { console.log(5) };//先提升函数声明
    var getName;//然后提升变量,不会赋值
    Foo.getName = function () { console.log(2) };
    Foo.prototype.getName = function () { console.log(3) };
    getName = function () { console.log(4) };
    最后执行getName()时自然输出的是4.
     
    第三问:先执行Foo(),首先在Foo函数的作用域里寻找变量getName,没有找到就到全局作用域里去寻找,找到了把getName重新赋值了一个匿名函数,最后返回的是window,相当于执行window.getName(),自然结果是1;
     
    第四问:此时已经把变量getName存储了function () { console.log(1) }的匿名函数。所以结果为1;
     
    后面的就牵扯到运算,优先级从高到底排序的,可以参考https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
    第五问:点.的运算符高于new所以相当于new (Foo.getName());访问对象Foo的静态属性getName(),实际上把getName当作构造函数,结果为2;
     
    第六问:
    new Foo().getName(),括号()的优先级高于new,
    相当于(new Foo()).getName();

    构造函数的返回值

    在传统语言中,构造函数不应该有返回值,实际执行的返回值就是此构造函数的实例化对象。

    而在js中构造函数可以有返回值也可以没有。

    1、没有返回值则按照其他语言一样返回实例化对象。

    2、若有返回值则检查其返回值是否为引用类型。如果是非引用类型,如基本类型(string,number,boolean,null,undefined)则与无返回值相同,实际返回其实例化对象。

    3、若返回值是引用类型,则实际返回值为这个引用类型。

    原题中,返回的是this,而this在构造函数中本来就代表当前实例化对象,遂最终Foo函数返回实例化对象。

    之后调用实例化对象的getName函数,因为在Foo构造函数中没有为实例化对象添加任何属性,遂到当前对象的原型对象(prototype)中寻找getName,找到了。

    遂最终输出3。

    第七问:
    new new Foo().getName(),相当于new ((new Foo()).getName)();先初始化Foo的实例化对象,然后将其原型上的getName函数作为构造函数再次new;
     
    参考:http://mp.weixin.qq.com/s/eO5hL0pcEHYr7jAbWTWAXg
     
     
     
     
     

          

  • 相关阅读:
    DAY 118 ES组合查询
    DAY 117 ES查询
    DAY 116 ES文档操作
    box_sizing
    添加视频
    网页自动刷新
    如何使网页宽度自动适应手机屏幕的宽度?
    存储过程&触发器
    mysql事务
    mysql常用语句
  • 原文地址:https://www.cnblogs.com/youtian/p/7860095.html
Copyright © 2011-2022 走看看