05-面向对象[原型属性及对象]

本文深入探讨了面向对象编程(OOP)的概念,包括字面量、new关键字、工厂模式和构造函数创建对象的方式及其优缺点。接着讲解了原型(prototype)的含义、作用、创建方法以及原型链的就近原则。最后分析了原型与构造函数方式的对比,并阐述了原型查找的优先级规则。内容涵盖了OOP中的核心概念和技术细节。
摘要由CSDN通过智能技术生成

面向对象编程(OOP)

意义:使用对象时,只关注对象提供的功能,不关注其内部细节

一、创建对象

(1)、字面量创建对象

<!-- //字面量方式创建对象 -->
    <script>
        var obj = {
            sex: '男', //添加属性 属性值(描述)
            name: '东东',
            //添加方法 行为
            buy: function() {
                console.log('吃饭');
            }
        }
        console.log(obj);
        console.log(obj.name); //东东
        console.log(obj['sex']); //男
        obj.buy(); //吃饭
    </script>

(2)、new关键字,实例创建对象

  • 缺点:造成代码冗余

<!-- 实例创建对象,(代码冗余) -->
    <script>
        var obj = new Object();
        //1、添加属性
        obj.name = '华子';
        obj.gender = '男';
        obj.play = function() {
            console.log('打篮球');
        }
​
        console.log(obj.name); //华子
        console.log(obj.gender); //男
        obj.play() //打篮球
    </script>

(3)、工厂模式创建对象

  • 缺点:结构不明确

  • 工厂函数:在函数内部常见对象,且用return出来给外部使用

  • 好处:外部不需要关注工厂函数里面具体是怎么实现的(隐藏细节)

<script>
        function factory(name, age) {
            //1、创建对象
            var obj = new Object(); 
            //2、添加属性及方法
            obj.myname = name;
            obj.myage = age;
             obj.skill = function () {    
            console.log('敲代码');
             }
            //3、返回创建好的对象
            return obj;
        }
​
        console.log(factory('东东', 14));
        console.log(factory('rose', 18));
 </script>

(4)、构造函数创建对象

  • 构造函数创建类(对象)

  • 在构造函数中只要是this点出来的属性和方法都是公开的(public)

  • 在构造函数内不使用this,用普通的函数创建和变量创建的就是私有的

  • 私有的方法和变量,都只能在构造函数内部使用,并且和外部没有关系(在外部仍然可以继续使用)

 <script>
        function Animal(type, name, age, sex) {
            this.myType = type;
            this.myName = name;
            this.myAge = age;
            this.mySex = sex;
​
            //私有的方法,虽然是写在animal里面,但是它是属于window的,本质上和anima对象无关
            //私有的方法,只能在animal里面使用
            var mySize = '2米';
​
            function introduce() {
                console.log('我身高' + mySize);
            }
​
            this.eat = function(food) {
                console.log(this.myName + '吃' + food);
            }
            this.sleep = function() {
                //私有方法
                introduce()
                console.log('睡觉');
            }
        }
        //创建一个animal类的实例
        //在构造函数中,只要是用this点出来的属性和方法就都是public的【公开的】
        var tiger = new Animal('爬行', '狮子', 11, '公');
        console.log(tiger.myName);
        tiger.eat('玉米');
        tiger.sleep() //我睡觉和2米
​
​
        //在外部又创建了一个公开的属性,也叫mySize
        tiger.mySize = '3米';
        console.log(tiger.mySize);
​
        //如何设计一些私有的private的属性和方法呢?
        //在构造函数中不要用this,就用普通的函数创建和变量创建就是私有的了
    </script>

二、原型(prototype)

含义:

  • 每个函数都有一个自带的prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法

  • 作用:提取类的共性,数据共享

语法:

(1)、获取原型对象

  • 每个函数都有一个内置的prototype(原型)属性

  • 构造函数名.prototype//返回原型对象

  • 实例对象名.__ proto __//返回原型对象

<script>
        function Person(name) {
            this.name = name;
        }
        //创建一个对象实例
        var p = new Person('东东')
        console.log(p);
        console.log(p.__proto__); //原型对象
        console.log(Person.prototype); //原型对象
​
        var arr = new Array();
        console.log(arr);
        console.log(arr.__proto__);
    </script>

(2)、创建原型属性

构造函数名.prototype 和 实例对象=.proto 是完全相等的

  1. 创建原型属性方法

    类名.prototype.方法名=function(){};
    实例对象名.__proto__.方法名=function(){}

  2. 创建原型属性属性

    类名.prototype.属性名=属性值;
    实例对象名.__proto__.属性名=属性值;

  3. 作用:减少某些函数去重复创建,减少代码冗余,数据共享的函数与属性

<script>
        function Student(name) {
            this.name = name;
        }
        // prototype原型的好处
        // 给构造函数上挂载一个原型prototype,目的是为了减少某些函数去重复创建
        // 减少代码冗余
        // 以后不论创建出来多少个对象,大家都共用原型属性里面的
​
        // prototype的作用:函数与属性共享的
​
        //1、创建共享方法
        Student.prototype.study = function() {
            //这个方法是共享函数,(所有student的实例都可以共享)
            console.log('学习');
        }
​
        //2、创建共享属性
        Student.prototype.school = '蜗牛学院';
​
        //3、创建两个对象实例
        var s1 = new Student('张三');
        var s2 = new Student('李四');
        console.log(s1);
        console.log(s2);
        s1.study();
        s2.study();
        console.log(s1.school);
        console.log(s2.school);
​
​
        //创建共享属性
        s1.__proto__.age = 1;
​
        console.log(s1.age); //1
        console.log(s2.age); //1
    </script>

(3)、给构造函数设置一个原型属性(prototype)

  • 创建的原型对象会覆盖住原来自带的原型

  • 语法:

  • 类名.prototype={}

  • 实例对象名.__ proto __={}//不知道行不,应该不行

<!-- 给构造函数设置一个原型,就是{},{}的原型就是Object -->
    <script>
        function Student(name) {
            this.name = name;
        }
        //给student设置一个原型,就是{},
        //相当于覆盖了原来自带的原型属性
        Student.prototype = {
            age: 18,
            sex: '男',
            study: function() {},
            love: function() {}
        }
        var s = new Student('东东')
        console.log(s.sex); //男
        console.log(s);
    </script>

  • 创建一个对象

    • var 对象名=Object.create({内容})

    • 里面的内容是创建的新原型

    • 在外面通过追加写的是实例里的方法和属性

<script>
        //1、对象默认的原型是object,
        console.log({
            name: '小明'
        });

        //2、创建一个没有原型的纯粹的对象
        var obj = Object.create(null);
        console.log(obj);

        //3、创建一个带有原型[{run:function(){}}]的对象
        var obj2 = Object.create({
            //原型
            run: function() {}
        })
        console.log(obj2);

        var obj3 = Object.create({
            //原型属性
            name: 'n'
        })
        //3、给这个对象追加实例属性
        obj3.sex = 'nan';
        console.log(obj3);
    </script>
  • 调用原型上的属性和方法时,不需要加__ proto __,直接写方法名/属性名即可

  • 当我们想要修改原型上的面的内容时,才需要通过__ proto __去进行修改

<script>
        function phone(type, icloud, color) {
            this.type = type;
            this.icloud = icloud;
            this.color = color;
        }

        phone.prototype = {
            call() {
                console.log(this.type);
            },
            message() {},
            internet() {},
        }
        var p = new phone('iPhone12', 'gysz12b110@xx', 'white')
        console.log(p);
        //获取原型上的属性和方法时,不需要加__ proto __,直接写名字即可
        p.call();
        // 当我们想要修改原型上面的内容时, 才需要通过__ proto 才需要通过__
        p.__proto__.call = function() {
            console.log('重置');
        }
    </script>

三、构造函数方式和原型方式对比

(1)、prototype原型的好处

  • 给构造函数上挂载一个原型prototype,目的是为了减少某些函数去重复创建

  • 给原型上的内容创建一次就行,以后无论创建对少个对象,大家都共用

  • 但是构造函数里面的内容,每new一次,就要创建一次,造成性能浪费

三、prototype原型优先级

原型模式的执行流程:(就近原则)

背景:当构造函数内部的成员与原型上的内容重名了,

寻找规则:就近原则

  1. 先查找构造函数实例里的属性和方法,如果有,立刻返回;

  2. 如果构造函数实例里面没有,则去它的原型对象里面找,如果有就返回

  3. 如果没有,属性返回underfined,方法返回not a function

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值