JS 综合面试题1

232 阅读3分钟
    <script>
        function Foo() {

            this.getName = function () {   // getName  公有方法
                alert(6);
                return {
                    getName: getName
                }
            };
            getName = function () {   // getName  全局变量
                alert(1)
            };
            return this;  //指向调用对象
        }

        Foo.getName = function () {
            alert(2)
        };

        Foo.prototype.getName = function () {
            alert(3)
        };

        var getName = function () {
            alert(4)
        };


        function getName() {
            alert(5)
        }

        //    请回答一下问题:

        Foo.getName(); // 调用方式2的函数代码块,结果为“2”

        getName(); //4

        //   如果单独看这条执行语句,一般会有个全局声明的函数方式5"function getName(){} ",
        // 但要是放在这么个复杂的上下文环境中,那肯定是不一样的啦,因为还有个方式4 
        // “var getName = function(){}” 来捣乱,这就要考察一个知识点(你妈和你媳妇掉水里,你救谁的问题?nonono,可没那么纠结)
        // ,当定义的变量和声明的函数重名了怎么办?答:它们都会进行预解析,函数声明提前于变量声明,但是最终会被变量覆盖!so方式4获胜,输出结果为“4”!

        Foo().getName(); //1
        //     本句,有个执行顺序的,先执行方式1的“Foo()”,结果是"this" 并指向window,
        // 并产生了一个全局getName(window.getName)指针指向一个匿名函数,然后再执行"this.getName()" , 
        // 其实就是执行刚刚造出来的那个全局getName指向的匿名函数,所以输出“1”.

        getName(); //1
        //此句执行的是方式1执行出来的那个全局变量getName 
        // 指针指向的匿名函数,有人问为啥不执行方式4?
        // 俺想说方式4已经被覆盖了!所以结果为 “1”.执行语句第五行:new Foo.getName()

        new Foo.getName(); //2
        //等价于new (Foo.getName()),先执行Foo.getName(),输出2,再创建Foo.getName()方法的实例。


        new Foo().getName(); //3
        //相当于(new Foo()).getName(),先创建Foo的实例,调用实例的getName()方法,由于自身没有该方法,
        // 去原型链上找,它的原型指向构造函数的prototype,即调用Foo.prototype.getName(),输出3


        new new Foo().getName(); //3
        //相当于new (new Foo().getName()),即先执行new Foo().getName(),
        // 由第六步可知,输出3,再创建Foo.prototype.getName()这个函数的实例返回。
    </script>
    
    **小结**
    // 一、作用域问题  


    //     function User(name){
    //         var name = name;  //局部变量  私有属性
    //         this.name = name;  // 公有属性
    //         function getName(){ // 私有方法
    //             return name;
    //         }
    //     }
    // User.prototype.getName = function(){// 公有方法
    //     return name;
    // }

    // User.name = "ls"; //静态属性
    // User.getName = function(){ //静态方法


    //     console.log(this)
    //     return this.name;

    // }


    // // natuo name -> 哪吒

    // //     name  -> 魔丸



    // var name = ""

    // console.log(  typeof  User.name)

    // var zs = new User('zs');   //构造函数 返回的是一个全新的对象  新对象的所有属性均来自 此构造函数

    // console.log(  zs.name )

    //  var n =   User.getName()


    // console.log(n)

    /****************************************************************/
    // 二、js执行阶段:
    // 1、预解析阶段:  检查有没有语法错误   变量的提升  函数声明的提升
    // 2、执行阶段:    变量的赋值 和  函数的调用

    // 三、定义函数
    // //a、 函数申明
    // function wechat(type) {
    //   return type = "wechat"
    // }

    // //b、 函数表达式
    // var wechat = function (type) {
    //   return type = "wechat"
    // }

    //c、区别 


    // 执行时:第一步: var  getNa  = undefinde   function getNa(){alert("2")};
    // getNa();//2

    // var getNa = function(){
    //     alert('1')
    // }
    // getNa();//1
    // function getNa(){
    //     alert("2")
    // };
    // getNa();//1

    /****************************************************************/
    // 四、作用域与作用域链    
    // //函数一旦声明 就存在作用域链:规定了如何去获取相对应的变量
/****************************************************************/
        // 五、js运算符优先级 

        // 优先级       运算符   
        //  19          ()
       //   18        new(有参数) /" . "     同级看位置的顺序
       //   17        new(无参数)