JS基础-使用工厂方法创建函数-构造函数-原型

JS基础

1、使用工厂方法创建对象

 //创建三个对象
    var obj = {
            name:"孙悟空",
            age:18,
            gender:"男",
            sayName:function(){
                alert(this.name)
                }
            };
    /*使用工厂方法创建对象
    *通过该方法可以大批量的创建对象
    */
    function createPerson(name,age,gender){//传入三个参数
        //创建一个新的对象
        var obj = new Object();
        //向对象中添加属性
        obj.name = name;
        obj.age = age;
        obj.gender = gender;
        obj.sayName = function(){
            alert(this.name);
        };
        //将新的对象返回
        return obj;
    }
    var obj1 = createPerson("白骨精",18,"女");//创建对象,传入参数
    var obj2 = createPerson("猪八戒",24,"男");
    var obj3 = createPerson("沙僧",25,"男");
    // console.log(obj1);//{name: '白骨精', age: 18, gender: '女', sayName: ƒ}
    // console.log(obj2);
    // console.log(obj3);
    obj3.sayName();//沙僧
    obj2.sayName();
    obj1.sayName();

 		/*
        *使用工厂方法创建的对象,使用构造函数都是Object
        *所以创建的对象都是Object这个类型,就导致我们无法区分出多种不同类型的对象
        */
        //创建狗对象
        function createDog(name,age){
            var obj = new Object();
            obj.name = name;
            obj.age = age;
            obj.sayHello = function(){
                alert("汪汪叫~~~");
            };
            return obj;
        }
        //创建一个狗的对象
        var dog = createDog("旺财",5);
        console.log(dog);//{name: '旺财', age: 5, sayHello: ƒ}
        dog.sayHello();

2、构造函数

        /*
        *创建一个构造函数,专门用来创建Person对象的
        *构造函数就是一个普通的函数,创建方式和普通函数没有区别,
        *不同的是构造函数习惯上首字母大写
        *
        *构造函数和普通函数的区别就是调用方式的不同
        *普通函数是直接调用,而构造函数需要使用new关键字来调用

        构造函数的执行流程:
            1.立刻创建一个新的对象
            2.将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
            3.逐行执行函数中的代码
            4.将新建的对象作为返回值返回

        使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类
        我们将通过一个构造函数创建的对象,称为是该类(构造函数)的实例

        this的情况:
            1.当以函数的形式调用时,this是window
            2.当以方法的形式调用时,谁调用方法this就是谁
            3.当以构造函数的形式调用时,this就是新创建的那个对象
        */
        function Person(name,age,gender){
            // alert(this);//this就是新建的对象->per
            this.name = name;
            this.age = age;
            this.gender = gender;
            this.sayName = function(){
                alert(this.name);
            };
        }

        // var per = Person();
        // console.log(per);// undefined(作为普通函数的调用情况,不加new)

        var per = new Person("孙悟空",20,"男");  
        var per1 = new Person("白骨精",18,"女");  
        var per2 = new Person("唐僧",22,"男");  
        console.log(per);
        console.log(per1);
        console.log(per2);
        // console.log(per.name);//孙悟空 (证明per对象中有name属性,this作为返回值赋值给per)

        function Dog(){

        }
        //创建一个dog对象
        var dog = new Dog();//dog是Dog类的一个实例
        console.log(dog);//Dog {}

        /*
        使用instanceof可以检查一个对象是否是一个类的实例
            语法:
                对象instanceof 构造函数
            如果是,则返回true,否则返回false
        */
        /*
        所有的对象都是Object的后代
        所以任何对象和Object作instanceof检查时都会 返回true
        */
        console.log(per instanceof Person);//true
        console.log(dog instanceof Object);//true

3、构造函数修改

  //创建一个Person构造函数
    /*
    在Person构造函数中,为每一个对象都添加了一个sayName方法,
        目前我们的方法是在构造函数内部创建的,
    也就是构造函数每执行一次就会创建一个新的方法sayName方法,
        也就是所有的实例sayName都是唯一的。
    这样就导致了构造函数执行一次就会创建一个新的方法
        执行1000次就会创建1000次新的方法,而1000个方法都是一摸一样的
        这是完全没有必要的,完全可以使所有的对象共享同一个方法
    
    */
    function Person(name,age,gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
        //向对象中添加一个方法
        // this.sayName = fun;//将函数赋值给this下面的属性

    }
    //将sayName方法在全局作用域中定义
    /*
    将函数定义在全局作用域,污染了全局作用域的命名空间
    而且定义在全局作用域中也很不安全
    */
    // function fun(){
    //         alert("Hello你好,我是"+this.name);
    //     };

    //向原型中添加sayName方法
    Person.prototype.sayName = function (){//所有的对象都可以访问到
            alert("Hello你好,我是"+this.name);
        };
    //创建一个Person的实例
    var per = new Person("小猪",22,"男");
    var per1 = new Person("小妞",20,"女");//备注:程序是从上往下开始一步步执行的,如果上面与下面实例一样,那么就按照下面的程序后执行
    // console.log(per);//Person {name: '小猪', age: 22, gender: '男', sayName: ƒ}
    // per.sayName();//Hello你好,我是小猪
    // console.log(per.sayName == per1.sayName);//false

    console.log(per);
    console.log(per1);//Person {name: '小妞', age: 20, gender: '女', sayName: ƒ}
    per.sayName();//Hello你好,我是小猪
    per1.sayName();
    console.log(per.sayName == per1.sayName);//true

4、原型对象

1、prototype
 //创建一个Person构造函数
    /*
    在Person构造函数中,为每一个对象都添加了一个sayName方法,
        目前我们的方法是在构造函数内部创建的,
    也就是构造函数每执行一次就会创建一个新的方法sayName方法,
        也就是所有的实例sayName都是唯一的。
    这样就导致了构造函数执行一次就会创建一个新的方法
        执行1000次就会创建1000次新的方法,而1000个方法都是一摸一样的
        这是完全没有必要的,完全可以使所有的对象共享同一个方法
    
    */
    function Person(name,age,gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
        //向对象中添加一个方法
        // this.sayName = fun;//将函数赋值给this下面的属性

    }
    //将sayName方法在全局作用域中定义
    /*
    将函数定义在全局作用域,污染了全局作用域的命名空间
    而且定义在全局作用域中也很不安全
    */
    // function fun(){
    //         alert("Hello你好,我是"+this.name);
    //     };

    //向原型中添加sayName方法
    Person.prototype.sayName = function (){//所有的对象都可以访问到
            alert("Hello你好,我是"+this.name);
        };
    //创建一个Person的实例
    var per = new Person("小猪",22,"男");
    var per1 = new Person("小妞",20,"女");//备注:程序是从上往下开始一步步执行的,如果上面与下面实例一样,那么就按照下面的程序后执行
    // console.log(per);//Person {name: '小猪', age: 22, gender: '男', sayName: ƒ}
    // per.sayName();//Hello你好,我是小猪
    // console.log(per.sayName == per1.sayName);//false

    console.log(per);
    console.log(per1);//Person {name: '小妞', age: 20, gender: '女', sayName: ƒ}
    per.sayName();//Hello你好,我是小猪
    per1.sayName();
    console.log(per.sayName == per1.sayName);//true

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UuT5z2lO-1644760247117)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220213211016715.png)]

2、prototype
//创建一个构造函数
        function MyClass(){

        }

        //向MyClass的原型中添加一个name属性
        MyClass.prototype.name = "我是原型中的名字";
        var mc = new MyClass();
        mc.age = 18;

        // console.log(mc.name);//我是原型中的名字

        //使用in检查对象中是否含有摸个属性时,如果对象中没有,但原型中有,也会返回为true
        // console.log("name" in mc);//true

        //可以使用对象的hasOwnProperty()来检查自身中是否含有该属性
        //使用该方法是只有当对象自身含有属性时,才会返回true
        console.log(mc.hasOwnProperty("age"));//true
        
        /*
        原型对象也是对象,所以它也有原型,
        当我们使用一个对象的属性或方法时,会先在自身中寻找,
        如果没有则去原型中寻找,如果原型对象中有则使用,
        如果没有则去原型的原型中寻找,直到找到Object对象的原型,
        Object对象的原型没有原型,如果在Object中依然没有找到,则返回undefined
        */

       // console.log(mc.hasOwnProperty("hasOwnProperty"));//false
        // console.log(mc.__proto__.hasOwnProperty("hasOwnProperty"));//false
        console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//true
        //原型链
        //console.log(mc.__proto__.__proto__.__proto__);//null

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R2Z96dS4-1644760247118)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220213214634106.png)]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潇潇_码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值