构造函数注意事项及构造函数创建对象存在问题

2017-02-25  本文已影响0人  码农的世界你不懂

01 构造函数内部设置方法(函数传值)函数传值:可以把构造函数的对象方法抽取为参数

<script>

    //001 创建一个构造函数
    function Person(name,age,toDoSomeThing) {

        //002 在构造函数内部设置对象的属性和方法
        this.name = name;
        this.age = age;

        this.sayName = function () {
            console.log(this.name);
        };

        this.toDoSomeThing = toDoSomeThing;
    }

    //003 使用构造函数创建对象
    var zhangsan = new Person("张三",18,function () {
        console.log("张三在读书");
    });

    var lisi = new Person("李四",20,function () {
        console.log("李四在玩耍");
    });

    //004 打印对象的属性
    console.log(zhangsan.name);
    console.log(zhangsan.age);
    console.log(lisi.name);
    console.log(lisi.age);

    //005 调用对象的方法
    console.log("__________________");
    zhangsan.sayName();
    zhangsan.toDoSomeThing();
    lisi.sayName();
    lisi.toDoSomeThing();
</script>

02 对象类型

检查对象的类型:instanceOf 获取对象的类型:Object.prototype.toString.call(dog)

function Dog(name) {
        this.name = name;
        this.color = "黄色";
    }
console.log(dog.constructor);
   **         属性的名称:constructor**

  ** 属性的作用:指向创建该对象的构造函数,类似于现实生活中所有的产品都标有生产厂家一样**
 //01 创建构造函数
    function Person() {
        this.name = "张三";
        this.age = 20;
        this.sayName = function () {
            console.log(this.name);
        }
    }

    //02 使用构造函数创建对象
    var p1 = new Person();
    var p2 = new Person;    //说明:如果不需要传递参数,则在调用构造函数的时候()可以省略
<script>

    //01 获得内置对象的类型
    var obj = {};
    console.log(obj.toString());

    var arr = [];
    console.log(arr.toString());    //无法获取正确的输出
    console.log(Object.prototype.toString.call(arr));   //[object Array]

    //02 创建构造函数
    function Dog() {
        this.name = "阿黄";
        this.color = "黄色";
    }

    //03 使用构造函数创建对象
    var dog = new Dog();

    //04 获得构造函数创建的对象的类型
    console.log(Object.prototype.toString.call(dog));   //[object Object] 并非Dog类型
    //思考:为什么dog对象的类型不是Dog?
    //解答:回想构造函数的执行过程,构造函数生成的对象是通过new Object()方式创建后赋值给this的,因此其类型为Object


    //instanceOf 用于检查对象的类型

</script>

03 对象的类型检查和构造属性

<script>

    //01 创建两个构造函数,分别用来构造Dog对象和Cat对象
    function Dog(name) {
        this.name = name;
        this.color = "黄色";
    }

    function Cat(name) {
        this.name = name;
        this.color = "黑色";
    }

    //02 创建具体的对象
    var dog = new Dog("阿黄");
    var cat = new Cat("小花");

    //03 验证dog和cat对象都是Object类型的
    console.log(dog instanceof Object); //true
    console.log(cat instanceof Object); //true
    console.log(dog instanceof Dog);    //true
    console.log(dog instanceof Cat);    //false
    console.log(cat instanceof Cat);    //true
    console.log(cat instanceof Dog);    //false


    //04 对象中的构造属性
    console.log(dog.constructor);       //该属性指向创建该对象的构造函数(类似于现实生活中所有的产品都标有生产厂家一样)
    console.log(cat.constructor);

    //console.log(dog.constructor.constructor);   //Function 函数的构造函数是Function
    //console.log(Dog.constructor.constructor);   //Function 的构造函数是本身
    console.log(Object.constructor);              //Function

</script>

示例:

<script>

    //01 创建构造函数
    function Person() {
        this.name = "张三";
        this.age = 20;
        this.sayName = function () {
            console.log(this.name);
        }
    }

    //02 使用构造函数创建对象
    var p1 = new Person();
    var p2 = new Person;    //说明:如果不需要传递参数,则在调用构造函数的时候()可以省略

    console.log(p1.name);
    console.log(p2.name);

    //03 直接调用构造函数
    //构造函数可以不通过关键new调用(注意:这是一种错误的演示)
    Person();
    console.log(window.name);   //张三
    window.sayName();           //张三

    //总结:如果通过new关键字调用构造函数,则this指向的是新创建出来的对象
    //    如果像调用普通函数一样调用构造函数,则this指向的是window全局对象
    //    因为在构造函数内部并为创建任何新的对象,this上面设置的属性和方法此时会被附加到window上面
    //    要谨防不通过new关键字直接调用构造函数


    //04
    function Person() {

        this.name = "张三";
        this.age = 20;
        this.sayName = function () {
            console.log(this.name);
        }
    }

</script>

总结:

如果通过new关键字调用构造函数,则this指向的是新创建出来的对象
如果像调用普通函数一样调用构造函数,则this指向的是window全局对象
因为在构造函数内部并为创建任何新的对象,this上面设置的属性和方法此时会被附加到window上面
要谨防不通过new关键字直接调用构造函数

–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

<script>

    //代码示例:提供一个构造函数,用于创建人对象,需要包含以下属性和方法
    //属性:学号、姓名、年龄
    //行为:吃饭、阅读

    //01 提供构造函数
    function Student(number,name,age) {

        //02 设置对象的属性
        this.number = number;
        this.name = name;
        this.age = age;

        //03 设置对象的方法
        this.eat = function () {
            console.log("eat");
        };
        this.read = function () {
            console.log("阅读");
        }
    }

    //04 创建学生对象
    var stu1 = new Student("20170201","张佳佳",18);
    var stu2 = new Student("20170202","刘小溪",20);

    //05 比较并验证对象的方法
    //说明:
    console.log(stu1.eat == stu2.eat);  //打印结果为false,说明每次创建对象,都会重新创建函数

    //问题:如果创建的对象数量很多,而对象方法内部的实现一模一样,则造成了资源浪费
</script>
<script>

    //01 提供构造函数
    function Student(number,name,age) {

        //02 设置对象的属性
        this.number = number;
        this.name = name;
        this.age = age;

        //03 设置对象的方法
        this.eat = eatFunction;
        this.read = function () {
            console.log("阅读");
        }
    }

    var eatFunction = function () {
        console.log("eat");
    };

    //04 创建具体的学生对象
    var stu1 = new Student("20170201","张佳佳",18);
    var stu2 = new Student("20170202","刘小溪",20);

    //05 比较并验证多个对象是否实现方法的共享
    console.log(stu1.eat == stu2.eat);  //true

    //尝试让所有的对象共用一个方法,在构造函数外部先定义好指定的函数,然后将该指定的函数赋值给函数内部的方法
    //06 == 等于符号补充
    //等于符号在进行比较的时候,只会比较值是否相等
    //在比较基本数据类型的时候,比较变量(表达式)对应的值[具体的数据]是否相等
    //在比较引用数据类型的时候,比较对象对应的值(引用地址)是否相等

</script>

① 全局变量增多,造成污染
② 代码结构混乱,不易维护
③ 函数可以不通过对象直接调用,封装性不好

上一篇下一篇

猜你喜欢

热点阅读