• JS面向对象经典题目(一)


    感觉这道题目是面向对象中比较经典了题目了.先上代码,然后分析

    1 function Foo(){
    2        getName = function(){console.log(1);};
    3        return this;
    4    }
    5    Foo.getName = function(){console.log(2);};
    6    Foo.prototype.getName = function(){console.log(3);};
    7    var getName = function(){console.log(4);};
    8    function getName(){console.log(5);}
    
    9    Foo.getName();//2
    10    getName();//4
    11    Foo().getName();//1
    12    getName();//1
    13    new Foo.getName();//2
    14    new Foo().getName();//3
    15    new new Foo().getName();//3

    做这道题时,首先要明白一点:就是一开始的函数申明,function Foo(),在没有调用之前,始终是不会运行的.
    1.Foo.getName()输出2!
    此处函数Foo()没有调用,不执行函数,后面的输出均于此函数什么时候调用有密切关系.
    此处的Foo是一个实例化对象,跟1行处的Foo除了同名再无其他关系.所以直接找到第5行处.这里第5行表示给Foo对象添加一个输出为2的方法.
    2.getName()输出4.
    此处直接调用getName(),1行处的函数未执行,从上往下寻找,首先找到
    第7行处,定义的getName对象.
    3.Foo().getName()输出1
    此处先运行Foo(),这里就调用第1行的函数了,运行后return一个this,这里调用Foo()的是window,所以this就指window。后面相当于window.getName()就直接找到函数内部getName()方法了.
    4.getName()输出1
    因为在3中已经执行过Foo()函数了,函数内部内容有效.getName()无直接写明调用对象,此处调用的对象就是window,函数体内部,getName也并未重新定义,而是一个全局的getName(即window的方法),此处直接找到第二行处.
    5.new Foo.getName()输出2
    这里涉及到运算符的优先级别:’运算的()’>’.’> ‘new’||’函数调用的()’ 。
    运算优先级表
    所以先执行5行处 Foo.getName()得到function(){console.log(2);}然后在 new function(){console.log(2);}
    6.new Foo().getName()输出3
    此处,先函数调用Foo(),接着运行new Foo(),再用new得到的这个实例化对象运行属性getName(),而getName()是通过6行处的原型链来定义的,所以找到第6行.
    7.new new Foo().getName()输出3
    此处有2个new,先执行右边的new Foo()得到一个实例化对象,这时,就无法运行左边的new了(总不至于new 后边跟一个实例对象吧),只能先运行后边的 .getName()得到一个函数,最后执行最左边的new.

  • 相关阅读:
    机器学习中的正/负样本
    机器学习算法需要注意的一些问题总结(特别有用!!!)
    Python操作Mysql数据库——多表组合查询
    Linux下MySql的配置文件my.cnf详细 讲解
    如何在windows下安装Python(Python入门教程)
    Linux 下安装JDK和jmeter 及环境配置记录过程
    下载JDK和Jmeter并设置系统环境变量
    charles4.2下载与破解方法以及配置https
    图解Fiddler如何抓取Android数据包
    Fiddler怎么可以抓取https的请求包
  • 原文地址:https://www.cnblogs.com/6long/p/6044501.html
Copyright © 2020-2023  润新知