js面向对象的一些小练习

今天来说一下js面向对象的小练习,废话不多说直接上练习,如果你能做出这个练习,说明你对js对象的一些知识已经很清晰了

一、代码



        function Foo(){
            getName = function(){
                alert(1);
            };
           return this;
        }

        Foo.getName = function (){alert(2);};
        Foo.prototype.getName=function () {alert(3);};
        var getName = function (){ alert(4);};
        function getName(){alert(5);}


// 写出下面的结果

        // 1 Foo.getName(); 
        // 2 getName(); 
        // 3 Foo().getName(); 
        // 4 new Foo.getName(); 
        // 5 new Foo().getName(); 
        // 6 new new Foo().getName(); 

怎么样你已经知道答案了么?

二、具体分析

1.Foo.getName(); 结果 弹出 2
分析:这个应该很简单,直接执行Foo.getName 函数表达式。

2.getName(); 结果 4 ,这个不难
分析:这里有一些知识点,我来详细的说一下,
① 当变量名字(没有赋值的情况下)和 函数名相同时,优先读取函数,也就是:

var getName
function getName(){alert(5);}

getName();  //结果会是5

3.Foo().getName(); 结果 1

这一块知识点比较多,我们来慢慢分析。

Foo() 函数执行完时,因为Foo()函数中返回了this, 当执行完时,Foo函数内的数据就暴露在了全局环境下,所以 返回的this 也就是Foo()指的是window,
那么你可能会说 在window下getName 函数有两个呀

getName = function(){
                alert(1);
            };

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

为啥不弹出 4, 原因在于var声明的变量被提升了,而 没有用var声明的变量没有被提升(属于全局变量),其次,函数中如果用var 声明的变量,它的作用域是在函数内的,这里没有用var 声明getName 函数表达式,所以Foo().getName() 结果为1 ;

4.new Foo.getName(); 结果 2

这个结果不知道你有没有想对,对于这个结果首先我们需要知道 new 操作符背后做了些什么。可以看一看我以前的文章http://blog.csdn.net/webxiaoma/article/details/65937768

其实在用new 操作符创建对象时,它背后给我们做的一些工作类似于:

var obj1= (function(){
    var o={}; //创建一个新对象
    o.__proto__=obj.prototype; //将新对象的原型链指向obj的原型
    obj.call(o,"hello")  //执行obj函数,将o对象指针指向obj函数,及o拥有了obj原型的属性和方法(引用)
    return o;
})()

这里new 出来的构造函数,会继承实例的原型上边的所有属性和方法。
这里弹出来的是 2 ,的原因是
① new操作符在执行时,执行了call 函数(或者apply函数),Foo.getName() 在new 创建对象时,在其内部执行了。你这里这样写new Foo.getName 也会弹出 2;

②这里生成的构造函数是Foo.getName 的构造函数,如果你不信,可以自己手动为Foo.getName的原型添加一个属性或方法(例如: Foo.getName.prototype.name = 4;),然后让后利用创建的构造函数去访问。

var ac = new Foo.getName();   
console.log(ac.name) // 4

5.new Foo().getName(); 结果是 3;
如果你上边的结果看懂了,那么这个你将很容易明白。这里和上边的唯一区别就是 函数 Foo 加了括号,这这个区别就改变了构造函数的实例,上边构造出来的函数的实例是Foo.getName,而这个构造函数的实例是 Foo 函数。
这里 new Foo().getName(); 的写法 其实就相当于:

var a = new Foo();
a.getName();

好了以上就是我分析的过程,如果有什么错误或问题,欢迎留言。

你可能感兴趣的:(javascript)