JavaScript-7

创建对象

    <script>
        // 方法一:new Object()
        const obj1 = new Object()
        obj1.name = 'Jack'
        console.log(obj1);

        // 方法二:字面量
        const obj2 = { name: 'Jack' }
        console.log(obj2);

        // 方法三:利用构造函数创建对象
        function Pig(name, age) {
            this.name = name
            this.age = age
        }
        console.log(new Pig('佩奇', 6));
    </script>

实例与静态成员

实例成员:
	通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员
	实例成员包含:实例属性和实例方法

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

说明:
	1.静态成员只能构造函数来访问
	2.静态方法中的this指向构造函数
    <script>
        // 构造函数
        function Person(name, age) {
            // 实例属性
            this.name = name
            this.age = age
            // 实例方法
            this.sayHi = function () {
                console.log('Hi');
            }
        }
        // 静态属性
        Person.eyes = 2
        Person.arms = 2
        // 静态方法
        Person.walk = function () {
            console.log('人都会走路');
            // 下面的 this 指向 Person
            console.log(this.eyes);
        }
    </script>

内置构造函数

Object

    <script>
        const obj1 = { name: 'Jack', age: 30 }

        // 获取所有的属性名
        console.log(Object.keys(obj1));     // 返回数组 ['name', 'age']

        // 获取所有的属性
        console.log(Object.assign(obj1));   // 返回数组 ['Jack', 30]

        // 追加对象属性
        const obj2 = {gender:'男'}
        Object.assign(obj2, obj1)   // 将obj1的属性追加到obj2
        console.log(obj2);
    </script> 

Array

  • reduce() 方法
    <script>
        // arr.reduce(function (上一次值, 当前值){...}, 初始值)

        arr = [1, 5, 8]

        // 1.没有初始值
        const total_1 = arr.reduce(function (prev, current) {
            return prev + current
        })      // 执行过程:1 + 5 => 6 + 8

        // 2.有初始值
        const total_2 = arr.reduce(function (prev, current) {
            return prev + current
        }, 10)  // 执行过程:10 + 1 => 11 + 5 => 16 + 8 => 24

        // 3.箭头函数的形式
        const total_3 = arr.reduce((prev, current) => prev + current, 10)
        console.log(total_3);   // 24
    </script>

String

  • split() 方法
    <script>
    	// split 把字符串转换为数组,刚好与join()相反
        const str = 'green|red'
        const arr = str.split('|')
        console.log(arr);   // ['green', 'red']
    </script>
  • substring() 方法
    <script>
        // 字符串的截取
        const str = '我一直都热爱这份事业'
        console.log(str.substring(1, 3));   // 输出结果: 一直
    </script>
  • startsWith() 方法
    <script>
    	// 判断字符串是否以xxx开头
        str = 'Hello World'
        alert(str.startsWith('He'))     // true
    </script>

Number

  • toFixed() 设置保留小数位的长度
    <script>
        // 数值类型
        const price = 12.345
        // 保留两位小数 四舍五入
        console.log(price.toFixed(2));  // 12.35
    </script>

原型

原型对象(prototype)

基本概念

  • 构造函数通过原型分配的函数是所有对象所共享的
  • JavaScript规定,每一个构造函数都有一个 prototype 属性
  • 这个属性,指向另一个对象,所以我们也称之为原型对象
  • 这个对象可以挂载函数,对象实例化不会多次创建在原型对象上
  • 我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法
  • 构造函数和原型对象中的 this 都指向实例化的对象

具体内容

    <script>
        // 公共的属性写到构造函数里面(每个对象自己都有一份,浪费内存)
        function People(name, age) {
            this.name = name
            this.age = age
            // this.sing = function() {
            //     console.log('唱歌');
            // }
        }

        // 公共的方法写到"原型对象"身上(所有对象共享,节约内存)
        People.prototype.sing = function () {
            console.log('唱歌');
        }

        // 实例化对象
        const obj1 = new People('Jack', 30)
        const obj2 = new People('Peter', 25)

        // 调用方法
        obj1.sing()
        obj2.sing()

        console.log(obj1.sing === obj2.sing);   // true
    </script>

案例演示

  • 给数组自定义的扩展一个"求和"的方法
    <script>
        // 数组
        const arr = [1, 2, 3]
        // 自定义方法
        Array.prototype.sum = function () {
            return this.reduce((prev, current) => prev + current, 0)
        }
        // 调用该方法
        console.log(arr.sum());
    </script>
  • 给数组自定义的扩展一个"最大值"的方法
    <script>
        // 数组
        const arr = [1, 2, 3]
        // 自定义方法
        Array.prototype.max = function () {
            return Math.max(...this)
        }
        // 调用该方法
        console.log(arr.max());
    </script>
  • 给数组自定义的扩展一个"最小值"的方法
    <script>
        // 数组
        const arr = [1, 2, 3]
        // 自定义方法
        Array.prototype.min = function () {
            return Math.min(...this)
        }
        // 调用该方法
        console.log(arr.min());
    </script>

constructor 属性

基本概念

  • 每个"原型对象"里面都有一个 constructor 属性(constructor 构造函数)
  • 作用:这个属性指向"该原型对象的构造函数"
    <script>
        function People() {
            // ...
        }
        console.log(People.prototype.constructor === People);   // true
    </script>

具体演示

当我们给"原型对象"一个一个的去添加"功能函数"时,会不会觉得非常的麻烦?下面的方法,能够快速的解决这个问题。

    <script>
        // 构造函数
        function People() {
            // ...
        }

        // People.prototype.sing = function () {
        //     console.log('唱歌');
        // }
        // People.prototype.dance = function () {
        //     console.log('跳舞');
        // }
        
        // 输出
        console.log(People.prototype)
        // 输出内容:
        // constructor: ƒ People()
        
        // 在修改原型对象的时候,除了添加你需要的函数功能
        // 请记得!还要添加"constructor:构造函数"
        // 以此实现"让它指回原来的构造函数"的目的
        People.prototype = {
            constructor: People,
            sing: function () { console.log('唱歌'); },
            dance: function () { console.log('跳舞'); }
        }
        
        // 输出
        console.log(People.prototype)
        // 输出内容:
     	// constructor: ƒ People()
		// dance: ƒ ()
		// sing: ƒ ()
    </script>

对象原型(__proto__

思考引入

问题

  • “构造函数"可以创建"实例对象”,“构造函数"还有一个"原型对象”
  • 一些公共的属性或者方法,可以放到"原型对象"上
  • 但是为什么"实例对象"可以访问"原型对象"里面的属性和方法呢?

答案

  • "实例对象"都会有一个__proto__属性
  • 这个属性,指向构造函数的"原型对象"
  • __proto__属性,我们称之为"对象原型"

注意事项

  • __proto__是 JS 非标准属性,用来表明"当前实例对象"指向哪个"原型对象"
  • [[prototype]]__proto__意义相同
  • __proto__里面也有一个constructor属性,指向创建该实例对象的"构造函数"
    <script>
        // 构造函数
        function People() { }
        // 实例对象
        const obj = new People()
        // 校验
        console.log(obj.__proto__.constructor === People);  // true
    </script>

原型继承

<script>
        // 构造函数(人)
        function People() {
            this.eyes = 2
            this.head = 1
        }

        // 构造函数(Woman)
        function Woman() {
            // ...
        }

        // Woman 通过原型对象prototype来继承Person
        Woman.prototype = new People()

        // 因为使用对象的赋值操作,所以prototype原来的constructor没了,我们需要手动添加回去
        Woman.prototype.constructor = Woman

        // 女人独有的能力
        Woman.prototype.beauty = function () {
            console.log('美丽动人')
        }

        // 构造函数(Man)
        function Man() {
            // ...
        }

        // 同上
        Man.prototype = new People()
        Man.prototype.constructor = Man

        // 男人独有的能力
        Man.prototype.handsome = function () {
            console.log('英俊潇洒')
        }

        // 创建对象
        const obj1 = new Woman()
        const obj2 = new Man()

        // 输出
        console.log(obj1.beauty())
        console.log(obj2.handsome())

        console.log(Woman.prototype)
        console.log(Man.prototype)
    </script>

原型链

基本认识

  • 基于原型对象的继承,使得不同构造函数的原型对象关联在一起
  • 并且这种关联的关系是一种链状的结构
  • 我们将这种原型对象的链状结构关系称为原型链

在这里插入图片描述

查找规则

  • 当访问一个对象的属性或方法时
  • 首先查找这个对象"自身"有没有该属性
  • 如果没有,就查找它的原型(也就是__proto__指向的prototype原型对象
  • 如果还没有,就继续向上查找
  • 依此类推,直到找到 Object 为止
  • __proto__对象原型的意义就在于,为对象成员查找机制提供一个方向,或者说一条路线
  • 可以使用 instanceof 运算符,去检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
    <script>
        function Person() { }
        const obj = new Person()
        
        console.log(obj instanceof Person)  // true
        console.log(obj instanceof Object)  // true
        console.log(obj instanceof Array)   // false
    </script>

面向对象编程案例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .btn {
            text-align: center;
        }

        .modal {
            margin: 200px auto;
            padding: 10px;
            width: 400px;
            height: 150px;
            box-shadow: 5px 2px 10px 2px rgba(0, 0, 0, 0.5);
            border-radius: 10px
        }

        .modal .header i {
            margin-left: 300px;
        }

        .modal .body {
            margin: 50px 0;
            text-align: center;
        }
    </style>
</head>

<body>
    <div class="btn">
        <button id="delete">注册</button>
        <button id="login">登录</button>
    </div>

    <script>
        // 1. 完成Modal构造函数的封装
        function Modal(title = '', message = '') {
            // 创建modalm=模态框盒子
            // 1.1 创建div标签
            this.modalBox = document.createElement('div')
            // 1.2 给div标签添加类名为modal
            this.modalBox.className = 'modal'
            // 1.3 modal盒子内部填充2个div标签,并且修改文字内容
            this.modalBox.innerHTML = `
            <div class="header">${title}<i>x</i></div>
            <div class="body">${message}</div>
            `
        }

        // 2. 给构造函数的原型对象挂载open方法
        Modal.prototype.open = function () {
            // 先来判断页面中是否有modal盒子,如果有先删除,没有就添加
            const box = document.querySelector('.modal')
            box && box.remove()
            document.body.append(this.modalBox)
            this.modalBox.querySelector('i').addEventListener('click', () => {
                this.close()    // 这个this指向实例对象
            })
        }

        // 3. 给构造函数的原型对象挂载close方法
        Modal.prototype.close = function () {
            this.modalBox.remove()
        }

        // 点击注册按钮
        document.querySelector('#delete').addEventListener('click', () => {
            const obj = new Modal('温馨提示', '您还没有登录呢')
            obj.open()
        })

        // 点击登录按钮
        document.querySelector('#login').addEventListener('click', () => {
            const obj = new Modal('友情提示', '您还没有注册呢')
            obj.open()
        })
    </script>
</body>

</html>
  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值