构造函数及原型

187 阅读6分钟

构造函数--是一种特殊的函数,主要用来初始化对象

使用场景:可以用构造函数来快速创建多个类似的对象

1、命名以大写字母开头

2、只能由"new"操作符来执行

说明:

1、使用new关键字调用函数的行为被称为实例化

2、实例化构造函数时没有参数可以省略()

3、构造函数内部无需写return,返回值即为新创建的对象

4、构造函数内部的return返回的值无效,所以不要写return

5、new Object() new Date() 也是实例化构造函数

构造函数和实例化名字要一致

 <script>
        function Phone(name, price, count) {
                this.name = name,
                this.price = price,
                this.count = count
        }

        const mi = new Phone('小米', '1999', '50')
        const oppo = new Phone('oppo', '5999', '5')
        const huawei = new Phone('小米', '8999', '25')
        console.log(mi);
        console.log(oppo);
        console.log(oppo);
    </script>

构造函数实例化过程

1、创建空新对象

2、构造函数this指向新对象

3、执行构造函数代码,修改this,添加新属性

4、返回新对象

实例成员

实例对象的属性和方法即为实例成员

实例对象相互独立,实例成员当前实例对象使用

静态成员

构造函数的属性和方法被称为静态成员

静态成员只能构造函数访问

内置构造函数

静态方法--只有构造函数Object可以调用

Object.values静态方法获取对象中所有属性值

Object.keys静态方法获取对象中所有属性名

注意:返回的是一个数组

   <script>
        const o = { name: "JUST OD IT", age: 6 }
        console.log(Object.keys(o));//['name', 'age']
        
        // 获取对象的所有值,并且返回一个数组
        const arr=Object.values(o)
        console.log(arr);//['JUST OD IT',6]
    </script>

Object.assign静态方法常用于对象拷贝

经常使用的场景:给对象添加属性

1、先创建一个带值的数组

2、在建一个空数组

3、然后把带值的数组拷贝到空数组

    const o = { name: "JUST OD IT", age: 6 }
        
        const oo={}
        Object.assign(oo,o)
        console.log(oo);//{name: 'JUST OD IT', age: 6}

        Object.assign(o,{gender:'女'})//{name: 'JUST OD IT', age: 6, gender: '女'} //直接将值拷贝给对象
        console.log(o);

reduce--返回累计处理的结果,经常用于求和

语法:arr.reduce(function(上一次的值,当前值){},初始值)

    <script>
        // 数组reduce方法
        // arr.reduce(function(上一次的值,当前值){},初始值)
        const arr = [1, 2, 3, 4, 5]
          //工作原理
          //p上一个数的值,首先是为0
            //p先前的值     c     计算后
            //0     1       1
            //1     2       3
            //3     3       6
            //6     4       10
            //10    5       15 
        // 1、没有初始值
        const total = arr.reduce(function (p, c) {
            return p + c
        })
        console.log(total);

        //2、有初始值--初始值为10
        //p的值此时就为10
        const totall = arr.reduce(function (p, c) {
            return p + c
        }, 10)
        console.log(totall);

        // 3、箭头函数写法
        const totalll = arr.reduce((p, c) => p + c, 10)
        console.log(totalll);
    </script>

reduce循环流程

1、如果没有初始值,则以上一次值以数组的第一个元素的值

2、每一次循环,把返回值给做为下一次循环的上一次值

3、如果有初始值,则起始值作为上一次值

  <script>
        const arr = [
            {
                name: '网易金',
                salary: 10000
            },
            {
                name: '网易金',
                salary: 10000
            }, {
                name: '网易金',
                salary: 10000
            }
        ]
        //如果是数组对象就以0作为初始值
        const total = arr.reduce((prev, current) => {
            return prev + current.salary
        }, 0)
        console.log(total);
    </script>

编程思想

JS----面向对象

1、每一个对象都是功能核心、具有明确分工

2、灵活、代码可复用,容易维护和开发,适合多人合作的大型项目

特性: 封装性、继承性、多态性

构造函数

体现了JS面向对象的封装性

封装的函数互不影响

原型---一个构造函数里的属性prototype,这个属性指向另一个对象。

构造函数中函数会多次创建,占用内存,引出把函数单独存储起来

当一个构造函数(Constructor Function)被定义时,它会自动获得一个名为prototype的属性。这个prototype属性是一个普通的对象,它默认只包含一个名为constructor的属性,该属性指向构造函数本身

语法: 构造函数.prototype

作用:

1、构造函数通过原型分配的函数是所有对象共享的

2、可以挂载函数,对象实例化之后不会多次创建原型上的函数,节约内存

3、可以把不变的方法定义在prototype对象身上,所有的对象实例就可以共享这些方法

4、构造函数中的this都指向实例化对象

    <script>
        function Star(name, age) {
                this.name = name,
                this.age = age
        }
        Star.prototype.fn = function () {
            console.log("JUSTODIT");
        }

        const LL = new Star('JUST', 18)
        const LP = new Star('just', 19)
        //调用原型 
        //调用实例上的方法,该方法实际上定义在Person的prototype对象上 
        LL.fn() //都会打印出JUSTODIT
        LP.fn()
    </script>

构造函数this指向

构造函数和原型对象中的this都指向实例化的对象

    <script>
        let JUST
        function Person(name) {
            this.name = name
            JUST = this
        }
        //创建一个实例化对象
        const just=new Person()
        //just是实例化对象,JUST是构造函数里的this指向
        console.log(just===JUST);//true
    </script>

利用原型this指向封装函数进行操作

    <script>
        //求最大值
        //...this展开运算符可以将数组里面的数字展开
        //this直接指向实例化对象
        Array.prototype.max = function () {
            return Math.max(...this)//this接收数组并展开数组
        }
        //this指向实例化对象--arr
        const arr = [1, 2, 3]
        console.log(arr.max());


        //求和
        Array.prototype.sum = function () {
            return this.reduce(function (pre, item) {
                return pre + item
            }, 0)
        }
        const arr2 = [4, 5, 6]
        console.log(arr2.sum());
    </script>

constructor属性

每个原型对象里面都有个constructor属性(constructor)

作用:该属性指向该原型对象的构造函数

constructor.jpg

   <script>
        // 创建一个构造函数
        function Just(name, age) {
            this.name = name,
                this.age = age
        }

        Just.prototype = {
            // 重新指回创造这个原型对象的构造函数
            constructor: Just,
            sing: function () {
                console.log("JUST OD IT");
            },
            dance: function () {
                console.log("justdoit");
            }
        }
        console.log(Just.prototype);
    </script>

对象原型

_proto_是JS非标准

[[prototype]]和_proto_意义相同

只读的,只能获取不能赋值

用来表明当前实例对象指向那个原型对象prototype

_proto_对象原型里面也有一个constructor属性,指向创建改实例对象的构造函数

11111.jpg

11111.jpg

<body>
    <script>
        function Star() {

        }
        const JUST = new Star()
        //原型对象_proto_指向 构造函数的原型对象
        console.log(JUST.__proto__);
        console.log(JUST.__proto__ === Star.prototype);
        //   对象原型里面有constructor 指向 构造函数 Star
        console.log(JUST.__proto__.constructor = Star);
    </script>
</body>

protype属性:

protype是原型对象

构造函数都自动有原型对象

constructor属性:

prototype原型和对象原型__proto__里面都有

都指向创建实例化对象/原型的构造函数

__proto__属性:

在实例化对象里面

指向原型prototype

原型继承

 //父类构造函数  子类构造函数
 //子类的原理=new 父类
   <script>
        function Person() {
            this.name = 'justdoit',
                this.age = 18
        }
        // 构造函数继承对象
        function Just() {

        }
        // 通过原型继承person---new Person--就可以互不干扰
        Just.prototype = new Person()
         //继承了之后要指回原来的构造函数
        Just.prototype.constructor = Just
        const just = new Just()
        console.log(just);
        // 构造函数继承对象
        function Any() {

        }
        Any.prototype = new Person()
        Any.prototype.constructor = Any
        const any = new Any()
        console.log(any);
    </script>

原型链--查找规则--

基于不同的原型对象继承使得不同的构造函数的原型对象关联在一起,并且这种关系是一种链状结构,这种链状结构就称为原型链 也就是__proto__的指向的指向

__proto__对象原型的意义在于为对象成员查找机制提供一个方向

QQ图片20240925203427.jpg

instanceof运算符--用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上

语法:谁 instanceof(属于) 谁

    <script>
        function Person() {

        }
        const just = new Person()
        console.log(just instanceof Person);//true
        console.log(Person instanceof Object);//true
    </script