js高级(代理,浅拷贝深拷贝,节流和防抖,闭包.hasOwnProperty)

news2024/11/24 10:25:09

1.代理

1.问题:如何定义一个对象,不会被修改,也不能被遍历?
  1. 通过Object.defineProperty(对象,属性名,option)定义默认属性

    • 无法被修改
    • 无法被删除
    • 无法被遍历

    注意:Object.Property传入的值与返回的值是同一个地址

  2. 可以配置一下属性

    • value:初始值
    • writable:true (true允许被修改)
    • enumerable:true(rue允许被遍历)
    • configurable:true(rue允许被删除)
  3. 提供get和set2个方法

    • 注意:get和set不能和value,writable一起使用,当给对象设置属性的值,会触发set
        //    var obj={}
        var o = Object.defineProperty({}, "name", {
            value: "刘德华",//初始值
            writable: true,//true 允许被修改
            enumerable: true,//true 允许被遍历
            configurable: true//true 允许被删除

        })
        //    delete o.name//删除
        // o.name="小易"//修改
        // for(let k in o){
        //     console.log(k,o[k]);//name 刘德华
        // }//遍历
        console.log(o);//{name: '刘德华'}
          var person = {
            name: "吴彦祖",
        }
        //给一个初始值
        person.age = 0
        // 问题:直接操作Person,给Person添加属性,容易出现值的不准确
        // 聘请一个代理(秘书)
        var proxy = Object.defineProperty({}, "age", {
            set(val) {
                if (!(val >= 18 && val <= 50)) {
                    console.log("值不合法");
                } else {
                    console.log("值合法");
                    person.age = val
                }
            },
            get() {
                return `年龄${person.age}`
            }
        })
        // 读写都要经过代理
        proxy.age = 22//设置年龄
        console.log(proxy.age);//读取年龄
        console.log(person);
2.查看方法有几个参数

使用arguments

3.hasOwnProperty
  1. 数组是特殊的对象,也就拥有对象的原型的属性和方法

  2. for…in会遍历原型上的属性和方法

    解决:

    • 使用Object.prototype.hasOwnProperty如果是原型上属性和方法,就为false,不是为true
  3. for…of 不会遍历原型上的属性和方法

    解决:

    • 使用Object.keys结合for…of
Object.prototype.address = "中国"
        function Person(name, age, sex) {
            this.name = name,
                this.age = age,
                this.sex = sex
        }
        var p = new Person("小易", 22, "女")
        // for..in会遍历到父的原型上的属性和方法
        for (let key in p) {
            console.log(key);//name, age, sex,address
        }
        // 解决方案1:使用Object.keys结合for..of
        var keys = Object.keys(p)
        for (let key of keys) {
            console.log(key);//name, age, sex
        }
        // 解决方案2:Object.prototype.hasOwnProperty如果是原型上属性和方法,就为false,不是为true
        for (let key in p) {
            // 如果是原型上属性和方法,就为false,不是为true
            console.log(key,Object.prototype.hasOwnProperty.call(p, key));
            if (Object.prototype.hasOwnProperty.call(p, key)) {
                const el = p[key]
                console.log(el);
               
            }
        }
4.浅拷贝

1.概念:除了第一层地址不共享,第二层以上的地址都共享,就是浅拷贝

2.对象的拷贝方法

  1. Object.assign()
  2. {…obj}

3.数组的浅拷贝

  1. […arr]
  2. arr.slice(0)
  3. [].concat(arr)
  4. arr.filter((item)=>item)
  5. _.clone(arr) lodash的方法
 var Person = {
            name: "老刘",
            age: 50,
            children: {
                name: "小刘",
                age: 20
            }
        }
        // 对象浅拷贝
        // 方法1 
        // var newPerson=Object.assign({},Person)
        // 方法二
        var newPerson = { ...Person }
        Person.name = "老老刘"
        Person.children.name = "小小刘"
        console.log(Person);
        console.log(newPerson);
        console.log(newPerson === Person);//false
        console.log(newPerson.children === Person.children);//true

        // 数组浅拷贝
        var arr = ["00", ["11", 22], { id: 1, name: "aa" }, { id: 2, name: "bb" }]
        // var arr1=[...arr]
        // var arr1=arr.slice(0)
        // var arr1=[].concat(arr)
        var arr1 = arr.filter(function(item){
            return item
        })

        arr1[0] = "99"
        arr1[1][0] = "zzz"
        console.log(arr1);
        console.log(arr);
   // 使用lodash的clone,实现浅拷贝,数组与对象的浅拷贝
        var arr=[11,[22,33],44]
        var arr1=_.clone(arr)
        arr[1][0]="zzzz"
        arr[0]="aaa"
        console.log(arr);
        console.log(arr1);

        var obj={id:1,name:"刘德华",children:{id:2,name:"小小易"}}
        var obj1=_.clone(obj)
        obj.name="zzzz"
        obj.children.name="ffff"
        console.log(obj);
        console.log(obj1);
5.lodash的使用

1复制lodash.js

.https://www.bootcdn.cn/lodash.js/

2.打开官网,查文档

https://www.lodashjs.com/

6.深克隆

1.如何判断引用类型?

1.Object.prototype.toString.call(对象名)

​ 2.constructor.name

2.实现深克隆的方法?

  1. js提供的

    JSON.stringify和JSON.parse能够实现深克隆,但是会丢失方法

  var p=JSON.parse(JSON.stringify(person0))
  1. 自己写

        //------------自己写深克隆---------
            var person0 = {
                id: 1,
                name: "蔡徐坤",
                children: {
                    id: 11,
                    name: "小刘"
                }
            }
            console.log(p);
            function deep(o) {
                let temp;
                if (Object.prototype.toString.call(o).includes("Object")) {
                    temp = {}
                } else if (Object.prototype.toString.call(o).includes("Array")) {
                    temp = []
                }
                for (const key in o) {
                    if (Object.hasOwnProperty.call(o, key)) {
                        // console.log(o[key]);
                        //    如果是引用数据类型,进行递归
                        if (typeof o[key] === "object") {
                            temp[key] = deep(o[key])
                            // console.log(deep(o[key]));
                        } else {
                            // 如果是值类型,直接赋值
                            temp[key] = (o[key])
                        }
    
                    }
                }
                return temp
            }
            var person1 = deep(person0)
            person0.children.name = "jj"
            // console.log(person0);
            // console.log(person1);
    
            /* 
                数组实现深克隆
            */
           var arr0=[11,[22,33],44]
           var arr1=deep(arr0)
           arr0[1][0]="hhh"
           console.log(arr0);
           console.log(arr1);
    
  2. 使用lodash cloneDeep

   var person2 = {
        id: 1,
        name: "蔡徐坤",
        children: {
            id: 11,
            name: "小刘"
        }
    }
    var person3 = _.cloneDeep(person2)
    person2.children.name = "mmmm"
    console.log(person2);
    console.log(person3);
7.闭包

1.概念:

函数嵌套函数,内部函数可以访问外部函数的变量和参数,变量和参数不会被垃圾回收机制所回收

2.闭包的好处

  1. 减少全局变量的污染
  2. 实现缓存

3.形成闭包的3个条件

  1. 函数嵌套函数
  2. 利用作用域(局部/全局)
  3. GC(垃圾回收机制)被使用就不会回收(标记清除法,引用计数法)

4.闭包的优点

  1. 保存变量,让一个变量长期驻扎在内存中,不会被释放’
 //    对于outer来说,a是局部变量
       function outer() {
            var a=100
             //    对于inner来说,a是全局变量
             function inner(){
                a+10
            }
            return inner
       }
       var f=outer()
       console.log(f);
8.节流和防抖

降低执行频率,稀释执行次数

​ 节流 throttle

  // 节流 throttle
       var box = document.querySelector(".box")
        box.onmousemove = throttle(function (e) {
            console.log(e);
            console.log(this);
            console.log(1);
        }, 100)
        // throttle页面加载执行
        function throttle(callback, delay = 600) {
            let start = Date.now()
            return function (e) {
                let end = Date.now()
                if (end - start >= delay) {
                    callback.bind(this)(e)
                    console.log(this);
                    console.log(e);
                    //给start重写标记开始的时间
                    start = end
                }
            }
        }

​ 防抖 debounce

   var box = document.querySelector(".box")
        // 防抖 debounce
        box.onmousemove = debounce(function (e) {
            console.log(e);
            console.log(this);
            console.log(1);
        }, 100)
        function debounce(callback, delay = 600) {
            var timer;
            return function (evt) {
                let self = this
                clearTimeout(timer)
                timer = setTimeout(function () {
                    console.log(this);
                    callback.call(self, evt)
                    // callback.call(self, evt);
                }, delay)
            }
        }

9.盒子拖拽.(原型链+继承+构造函数)

<!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>
        .box {
            width: 100px;
            height: 100px;
            background-color: pink;
            position: absolute;
        }

        .boxRed {
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            top: 115px;
        }

        .boxYellow {
            width: 100px;
            height: 100px;
            background-color: yellow;
            position: absolute;
            top: 300px;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <div class="boxRed"></div>
    <div class="boxYellow"></div>
    <script>
        // 原型拖拽
        function DragBox(cls) {
            this.el = document.querySelector(cls)
        }
        DragBox.prototype = {
            constructor: DragBox,
            dragStart() {
                let self = this
                this.el.onmousedown = function (e) {
                    let disX = e.offsetX
                    let disY = e.offsetY
                    self.dragIng(disX, disY)
                    self.dragEnd()
                }
            },
            dragIng(x, y) {
                let self = this
                document.onmousemove = function (e) {
                    console.log(this);
                    self.el.style.left = e.pageX - x + "px"
                    self.el.style.top = e.pageY - y + "px"
                }
            },
            dragEnd() {
                document.onmouseup = function () {
                    document.onmousemove = document.onmouseup = null
                }
            },
        }
        new DragBox(".box").dragStart()
        // 红色继承
        function DragBoxLimit(el) {
            DragBox.call(this, el)
        }
        DragBoxLimit.prototype = new DragBox;
        DragBoxLimit.prototype.dragIng = function (x, y) {
            let self = this;
            document.onmousemove = function (e) {
                let mX = e.pageX - x
                let mY = e.pageY - y
                if (mX < 0) {
                    mX = 0
                }
                if (mY < 0) {
                    mY = 0
                }
                self.el.style.left = mX + "px"
                self.el.style.top = mY + "px"
            }
        }
        new DragBoxLimit(".boxRed").dragStart()
        // 黄色继承
        function DragBoxLimitText(el) {
            DragBox.call(this, el)
        }
        DragBoxLimitText.prototype = new DragBox;
        DragBoxLimitText.prototype.dragIng = function (x, y) {
            let self = this;
            document.onmousemove = function (e) {
                let mX = e.pageX - x
                let mY = e.pageY - y
                if (mX < 0) {
                    mX = 0
                }
                if (mY < 0) {
                    mY = 0
                }
                self.el.style.left = mX + "px"
               
                self.el.style.top = mY + "px"
                self.el.innerHTML = "top:" + self.el.style.top + "<br>left:" + self.el.style.left
            }
        }
        new DragBoxLimitText(".boxYellow").dragStart()
       
    </script>
</body>

</html>

10.盒子拖拽(类)


<!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>
        .box {
            width: 100px;
            height: 100px;
            background-color: pink;
            position: absolute;
        }

        .boxRed {
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            top: 115px;
        }

        .boxYellow {
            width: 100px;
            height: 100px;
            background-color: yellow;
            position: absolute;
            top: 300px;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <div class="boxRed"></div>
    <div class="boxYellow"></div>
    <script>
        class box {
            constructor(el) {
                this.el = document.querySelector(el)
            }
            dragStart() {
                let self = this
                this.el.onmousedown = function (e) {
                    let disX = e.pageX-this.el.offsetLeft
                    let disY = e.offsetY
                    self.dragIng(disX, disY)
                    self.dragEnd()
                }
            }
            dragIng(x, y) {
                let self = this
                document.onmousemove = function (e) {
                    console.log(this);
                    self.el.style.left = e.pageX - x + "px"
                    self.el.style.top = e.pageY - y + "px"
                }
            }
            dragEnd() {
                document.onmouseup = function () {
                    document.onmousemove = document.onmouseup = null
                }
            }
        }
        class yellowBox extends box {
            constructor(el) {
                super(el)
                // this.left=e.pageX-e.offsetX
            }
            dragIng(x, y) {
                let self = this
                document.onmousemove = function (e) {
                    console.log(this);
                    self.el.style.left = e.pageX - x + "px"
                    self.el.innerHTML = "left:" + self.el.style.left
                    self.el.style.top = e.pageY - y + "px"
                    self.el.innerHTML = "top:" + self.el.style.top + "<br>left:" + self.el.style.left
                    console.log( self.el.style.left);
                }
            }
        }
        class RedBox extends box {
            constructor(el) {
                super(el)
                // this.left=e.pageX-e.offsetX
            }
            dragIng(x, y) {
                let self = this
                document.onmousemove = function (e) {
                    console.log(this);
                    let mX = e.pageX - x
                    let mY = e.pageY - y
                    if (mX < 0) {
                        mX = 0
                    }
                    if (mY < 0) {
                        mY = 0
                    }
                    self.el.style.left = mX + "px"
                  
                    self.el.style.top = mY + "px"

                }
            }
        }
        var b = new yellowBox(".boxYellow")
        var p = new box(".box")
        var r=new RedBox(".boxRed")
        r.dragStart()
        b.dragStart()
        p.dragStart()
    </script>
</body>

</html>

11.tab栏切换

在这里插入图片描述

 var Main = document.querySelectorAll(".main")
    for (var i = 0; i < TabItem.length; i++) {
        TabItem[i].onclick = change(i)//change会被执行4次
        // console.log(TabItem[i].onclick);
    }
    function change(n) {
        return function (e) {
            for (var i = 0; i < TabItem.length; i++) {
                TabItem[i].className = "tab-item"
                // 下面的图片
                Main[i].className = "main"
            }
            // e.target.className="tab-item active"
            this.className = "tab-item active"
            console.log(this);
            // 下面的图片
            Main[n].className = "main selected"
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1071481.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sylar高性能服务器-日志(P1-P6)代码解析+调试分析

文章目录 一、整体结构二、LogEvent三、LogLevel四、LogFormatter五、LogAppender六、Logger七、调试7.1调试步骤7.2尝试使用gdb调试 八、附录8.1log.h8.2log.cc8.3test.cc8.4Cmakelists.txt8.4Cmakelists.txt ​ 本篇文章主要针对一下sylar高性能服务器项目视频p1-p6的代码分析…

大华智慧园区管理平台任意密码读取漏洞 复现

文章目录 大华智慧园区管理平台任意密码读取漏洞 复现0x01 前言0x02 漏洞描述0x03 影响平台0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 大华智慧园区管理平台任意密码读取漏洞 复现 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&…

shell定时清理日志文件、及crontab说明

服务器日志文件一般是每天一个或多个文件&#xff0c;如果日志文件不清理&#xff0c;时间久了就会将磁盘空间占满&#xff0c;从而影响系统的正常运行。 1、分析磁盘空间占用情况 1.1、df 命令 df 命令以磁盘分区为单位查看文件系统中磁盘空间的使用情况。 语法&#xff1a;…

python基础教程:类class

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 class 定义一个类 class 定义一个类, 后面的类别首字母推荐以 大写 的形式定义&#xff0c;比如Calculator. 冒号不能缺 class可以先定义自己的属性&#xff0c…

Java 面向对象的三大特性

面向对象编程有三大特征: 封装、继承和多态。 1.封装 1&#xff09;封装介绍 封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起数据被保护在内部.程序的其它部分只有通过被授权的操作[方法],才能对数据进行操作。 2&#xff09;封装的理解和好处 隐…

Windows安装Node.js

1、Node.js介绍 ①、Node.js简介 Node.js是一个开源的、跨平台的JavaScript运行环境&#xff0c;它允许开发者使用JavaScript语言来构建高性能的网络应用程序和服务器端应用。Node.js的核心特点包括&#xff1a; 1. 事件驱动: Node.js采用了事件驱动的编程模型&#xff0c;通…

美股游戏股分析:微软收购游戏公司动视暴雪将迎来一个重要里程碑

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结&#xff1a; &#xff08;1&#xff09;微软(MSFT)收购动视暴雪(ATVI)的交易在做出重大让步后目前已经获得了欧盟和美国的监管批准。 &#xff08;2&#xff09;英国英国竞争和市场管理局(CMA)最初对微软收购动视暴雪…

SpringCloud Alibaba - 分布式事务理论(CAP 定理 和 BASE 理论)

目录 一、分布式事务理论 1.1、分布式事务问题 1.2、什么是分布式事务 1.3、解决分布式事务思路 1.3.1、CAP 定理 a&#xff09;Consistency&#xff08;一致性&#xff09; b&#xff09;Availability&#xff08;可用性&#xff09; c&#xff09;Partition tolerance…

反向生成:根据mybatis生成的Class实体类对象反向生成建表语句

微信公众号&#xff1a;大数据高性能计算 针对数据库不小心被删除的情况&#xff0c;以及需要逆向查看某个开源项目数据库表的情况时&#xff0c;往往需要逆向工程。 在这里我们假设 id 字段为主键。在生成 SQL 建表语句时&#xff0c;我们添加了 PRIMARY KEY (id) 来定义 i…

温控仪工作原理

温控仪的工作原理&#xff0c;是通过温度探头或热电偶反馈的电信号&#xff0c;温控仪将得到的电信号转化成温度值&#xff0c;根据设定的温度值&#xff0c;控制加热器的接通和断开来达到控制温度范围的&#xff1a; 1、温度探头或热电偶受温度变化时&#xff0c;会产生微弱的…

CDN技术与企业网站建设:解决疑问与明智选择

介绍CDN技术与疑问 在数字时代&#xff0c;网站是企业线上存在的门户&#xff0c;因此网站的性能和安全至关重要。为了解决一些与网站建设和性能相关的疑问&#xff0c;让我们首先来了解CDN技术。 什么是CDN技术&#xff1f; CDN&#xff0c;即内容分发网络&#xff08;Conte…

Langchain-Chatchat项目:1.2-Baichuan2项目整体介绍

由百川智能推出的新一代开源大语言模型&#xff0c;采用2.6万亿Tokens的高质量语料训练&#xff0c;在多个权威的中文、英文和多语言的通用、领域benchmark上取得同尺寸最佳的效果&#xff0c;发布包含有7B、13B的Base和经过PPO训练的Chat版本&#xff0c;并提供了Chat版本的4b…

【重拾C语言】六、批量数据组织(四)线性表—栈和队列

目录 前言 六、批量数据组织——数组 6.1~3 数组基础知识 6.4 线性表——分类与检索 6.5~7 数组初值&#xff1b;字符串、字符数组、字符串数组&#xff1b;类型定义 typedef 6.8 线性表—栈和队列 6.8.1 栈&#xff08;Stack&#xff09; 全局变量 isEmpty() isFull…

TCP原理特性详解

文章目录 可靠传输机制1.确认应答2.超时重传2.连接管理1.三次握手2.四次挥手 传输效率1.滑动窗口2.流量控制3.拥塞控制4.延时应答5.捎带应答 面向字节流粘包问题 TCP异常情况 可靠传输机制 可靠性&#xff1a;即发送方知道数据是发送成功了&#xff0c;还是失败了。 1.确认应答…

Github-使用2FA验证:使用python实现TOTP验证,python实现github的2FA验证

github新增了2FA验证了&#xff0c; 1、扫描二维码&#xff0c;获取对应字符串 或点击setup key ,获取字符串 2、使用python来生成校验码 安装&#xff1a; pip install pytop import pyotp key XKDRR4WH3LY2WXPH print(pyotp.TOTP(key).now()) 3、将生成的6个验证码&…

第一章 概述 | 计算机网络(谢希仁 第八版)

文章目录 第一章 概述重要内容计算机网络的一些相关知识互联网概述因特网的标准化工作互联网的组成计算机网络的类别计算机网络的性能指标计算机网络的体系结构——-分层次的体系结构 第一章 概述 重要内容 互联网边缘部分和核心部分的作用&#xff0c;以及分组交换的概念 计…

学习记忆——宫殿篇——记忆宫殿——记忆桩——身体——记忆星座

我们在与人攀谈的时候&#xff0c;可以从以下几个维度入手&#xff0c;如&#xff1a;年龄、星座、爱好、工作等。 两点记忆的技巧以及一点知识延伸 两点记忆技巧&#xff1a; 1、第一次见面时要创建回忆线索 2、脑中回忆交流画面&#xff0c;加深线索 一点知识延伸&#xff1…

NoSQL之Redis 主从复制配置详解及哨兵模式

目录 1 Redis 主从复制 1.1 主从复制的作用 1.2 主从复制流程 2 搭建Redis 主从复制 2.1 安装 Redis 2.2 修改 Redis 配置文件&#xff08;Master节点操作&#xff09; 2.3 修改 Redis 配置文件&#xff08;Slave节点操作&#xff09; 2.4 验证主从效果 3 Redis 哨兵模…

自动拟人对话机器人在客户服务方面起了什么作用?

在当今数字时代&#xff0c;企业不断寻求创新的方法来提升客户服务体验。随着科技的不断进步和消费者期望的提升&#xff0c;传统的客户服务方式逐渐无法满足现代消费者的需求。因此&#xff0c;许多企业正在积极探索利用新兴技术来改进客户服务&#xff0c;自动拟人对话机器人…

javaScript关于闭包的理解

首先在了解闭包之前&#xff0c;我们要了解一下环境和作用域 1.环境和作用域 日常生活中我们生活的环境由周边建设如公园&#xff0c;小区&#xff0c;超市构成的。这就构成了环境 在计算机当中环境就是一块内存的数据。 环境是有作用范围的&#xff0c;eg:武汉周边的建设一…