美文网首页
面向对象(三)构造函数注意事项

面向对象(三)构造函数注意事项

作者: 凸小布 | 来源:发表于2017-02-23 20:09 被阅读5次

    构造函数注意事项

    • 01函数传值
    • 02对象的类型(判断)
    • 03构造器属性(获取)
    • 04函数调用
    • 05this

    构造函数创建对象存在的问题

    • 每创建一个对象,内部都会声明一个showName函数

    01函数传值普通版

    <script>
        function Student(number, className){
            this.number = number;
            this.className = className;
            this.log = function(){
                console.log(this.number + '-' + this.className);
            }
        }
        var stu1 = new Student('0001','王者荣耀01班');
        var stu2 = new Student('0002','王者荣耀01班');
        console.log(stu1);
        console.log(stu2);
        stu1.log();
        stu2.log();
    </script>
    

    01函数传值升级版

    <script>
        function Student(number, className, log){
            this.number = number;
            this.className = className;
            this.log = log;
        }
        var stu1 = new Student('0001','王者荣耀01班', function(){
            console.log("hello hello hello" + '-' + this.number);
        });
        var stu2 = new Student('0002','王者荣耀01班', function(){
            console.log("world world world" + '-' + this.className);
        });
        console.log(stu1);
        console.log(stu2);
        stu1.log();
        stu2.log();
    </script>
    

    02 对象的类型(判断)

    关键字 instanceOf
    用来判断当前对象是否是某个类型的实例(检查某个对象是否是使用指定构造函数创建的)
    语法: 对象 instanceOf 构造函数(类型)

    <script>
        function Person(){};
        function Dog(){};
    
        var p1 = new Person();
        var dog1 = new Dog();
    
        console.log(p1 instanceof Person); //true
        console.log(p1 instanceof Dog); //false
        console.log(dog1 instanceof Person); //false
        console.log(dog1 instanceof Dog); //true
    </script>
    

    03 构造器属性(获取)

    <script>
        function Person(){};
        function Dog(){};
    
        var p1 = new Person();
        var dog1 = new Dog();
    
        console.log(p1.constructor);  //Person
        console.log(dog1.constructor);//Dog
    </script>
    

    04 函数调用

    new :创建对象,并在最后返回该对象
    构造函数:用于初始化对象
    可以以普通函数的方式来调用构造函数(这是一个错误的演示,不要这样写代码)

    <script>
        function Person(name) {
            this.name = name;
            console.log(this);
        }
    
        var p1 = new Person("哈哈哈");
        console.log(p1);
        var p2 = Person('王者农药');
        console.log(p2); //undefined
    </script>
    

    以上代码存在的问题

    01 用调用普通函数的方式调用构造函数(没有报错)
    02 打印p2,得到的是undefined
    03 通过打印this,可以知道,用调用普通函数的方式调用构造函数,this属于window

    为了解决以上代码存在的问题,需在构造函数中多加一层判断,如下

    <script>
        function Person(name) {
            if(this instanceof Person){
                this.name = name;
            } else {
                return new Person(name);
            }
        }
    
        var p1 = new Person("哈哈哈");
        console.log(p1);
        var p2 = Person('王者农药');
        console.log(p2); //Person
    </script>
    

    05 this

    以普通函数的方式来调用构造函数,那么内部的this指向的是window,代码同上

    <script>
        function Person(name) {
            if(this instanceof Person){
                this.name = name;
            } else {
                return new Person(name);
            }
        }
    
        var p1 = new Person("哈哈哈");
        console.log(p1);
        var p2 = Person('王者农药');
        console.log(p2); //Person
    </script>
    

    构造函数创建对象存在的问题

    • 每创建一个对象,内部都会声明一个showName函数
    <script>
        function Person(name,age){
            this.name = name;
            this.age = age;
            this.showName = function(){
                console.log("姓名:");
            };
        }
        //创建对象
        var p1 = new Person("张小花",18);
        var p2 = new Person("张全蛋",99);
        p1.showName();
        p2.showName();
    
        //每创建一个对象,内部都会声明一个showName函数
        console.log(p1.showName == p2.showName);  //false
        
    </script>
    
    • 在内存中的结构图


      每创建一个对象,内部都会声明一个showName函数
    • 优化方案(也存在问题)
      问题:
      01 把函数写在外部,破坏了封装性。
      02 增加一个全局变量。

    <script>
    
        var showName = function(){
            console.log("姓名:");
        }
    
        function Person(name,age){
            this.name = name;
            this.age = age;
            this.showName = showName;
        }
    
        //创建对象
        var p1 = new Person("张小花",18);
        var p2 = new Person("张全蛋",99);
        p1.showName();
        p2.showName();
    
        //每创建一个对象,内部都会声明一个showName函数
        console.log(p1.showName == p2.showName);  //true
    </script>
    
    • 在内存中的结构图


      构造函数优化

    终极版:原型解决构造函数创建对象的问题

    <script>
        function Person(name,age){
            this.name = name;
            this.age = age;
    
        }
        var p1 = new Person("张小花",18);
        var p2 = new Person("张全蛋",99);
    
        Person.prototype.showName =function (){
            console.log("momo");
        };
    
        //设置原型对象的属性和方法的时候:构造函数.prototype.属性
        //对象.prototype.属性
    
        //创建对象
    
        p1.showName();
        p2.showName();
    
        console.log(p1.showName == p2.showName);
    </script>
    

    相关文章

      网友评论

          本文标题:面向对象(三)构造函数注意事项

          本文链接:https://www.haomeiwen.com/subject/zynbwttx.html