第三周总结(下)

2021-10-24  本文已影响0人  啊谢aaa

创建对象

字面量的方式

这种方式在日常开发过程中常用到,例如:const obj ={ name:"悟空",height:100,age:5000};,这种方式的缺点是不适合创建多个同样类型的对象的场景,优点是方便书写。

工厂模式

本质是,一种代码的复用,也是一种设计模式。以函数的形式复用了结构,这种简化获取相同结构对象的函数,叫做工厂模式。
例如:

let stu1={name:"安琪拉",gender:'女',height:168,stuId:"001"}
function createStudent(name,gender,height,stuId){
        return {name,gender,height,stuId}
}
let stu2=createStudent("亚瑟","男",186,'002')
console.log(stu1,stu2)

缺点:所有东西造出来都一样,都属于Object,无法区分对象,就无法分类管理。要想区分,自定义构造函数,不同的对象来源于不同的构造函数。

构造函数

作用:①用来产生对象,调用函数时,使用new关键字;②分类对象,给不同的对象提供不同的功能和数据。
特点:

  1. 函数名使用大驼峰的写法;
  2. 添加东西,就直接使用this.属性名,然后赋值;
  3. 函数内部不需要return;

优点:①方便地创建了对象;②而且在对象上创建的属性,能和对象产生直接的联系;
构造函数代码举例:

// 1.声明函数
function CreateStudent(name,age){
      // this就是obj
     // 通过this赋值
     this.name=name
    this.age=age
}
// 3. 通过new创建对象
const obj=new CreateStudent('猪八戒','130')
console.log(obj)

关键字new都做了那些事情:

  1. 在堆中开辟一块内存;
  2. 创建一个新的空对象;
  3. 调用构造函数(为对象赋值):新对象.构造函数,构造函数的this指向对象;
  4. 将对象的内存地址返回到new处;

构造函数的缺点
代码:

 function createStudent(name, age) {
      this.name = name;
      this.age = age;
      this.say = function () {
        console.log(this.name);
      }
    }
    const obj = new createStudent("悟能", 83);
    const obj1 = new createStudent("悟能1", 84);
    console.log(obj.say === obj1.say); // false  不是同一say方法 浪费了内存

问题描述:new一次就会开辟一个新的对象内存空间,方法也就会在每个对象内存中存储一份,这就导致内存占用严重
解决方案

 // 提前将say 声明好
    function say() {
      console.log(this.name);
    }
    function createStudent(name, age) {
      this.name = name;
      this.age = age;
      this.say = say
    }
    const obj = new createStudent("悟能", 83);
    const obj1 = new createStudent("悟能1", 84);
    console.log(obj.say === obj1.say); // true

但是,这种思路有产生了新问题,虽然解决了浪费内存的问题,但是也造成了全局污染。

创建函数

第一种,具名函数

fn();//函数声明可以先调用,在声明
function fn(参数..){
  console.log("这是函数声明")
  return 返回值
}

第二种,函数表达式(匿名函数)

const fn = function() {
  console.log("这是函数表达式");  
}
fn();//函数表达式必须先声明,再调用

第三种,构造函数的写法

const fn1 = new Function("a1", "a2", "alert(a1+a2)");
fn1(1,2);

这种写法,本人认为是最正规的写法,直接告诉使用者所有的函数都是由Function创建的。

闭包

闭包又被称为函数闭包,内部函数用到了外部函数的局部变量,这种现象就叫做闭包。
闭包的作用:

  1. 让数据变得更加安全;
  2. 函数内部返回另一个函数;

注意:

  1. 闭包一定是返回调用的函数,两层函数,外层放数据,内层做逻辑处理。
  2. 外层函数,返回内层函数,内层返回具体数据。
  3. 闭包只做数据加工,不做效果。

示例代码:

<h1></h1>
<button>点击</button>
<script>
// arr=[{name:"金"},{name:"木"},{name:"水"},{name:"火"},{name:"土"}] 
function show(){
let arr=[{name:"金"},{name:"木"},{name:"水"},{name:"火"},{name:"土"}];
let index=-1
return ()=>{
index++
if(index>=arr.length)index=0
return arr[index].name
            }
        }
let data=show()
document.querySelector('h1').innerHTML=data()
document.querySelector("button").onclick=function(){
document.querySelector('h1').innerHTML=data()
        }
// 外面的函数只调用一次,即能使变量没有重置,又保护了变量数据的安全
</script>

闭包的缺陷和解决方案

缺陷:占用了内存。
解决方案:将占用函数的变量释放掉,占用链断裂,垃圾回收机制立即回收。如果进行闭包释放,接收闭包函数的时候,不要const,否则不能二次赋值。使用let则可以释放。
闭包虽然有占用内存的缺陷,实际上很少释放,所以默认不允许占用内存。

递归

递归,就是函数自己调用自己。利用空间换时间,同时让N个相同的函数执行内存就会不断地被占用,
狭义递归解决问题的方式:

  1. 必须是函数:函数内部调用自己;
  2. 先解决大问题,然后通过规模变小后,再调用自己去解决小问题;

递归的两要素:

  1. 递归点:在函数解决问题的过程中,发现小问题(规模变小,性质一样),调用自己(参数规模减小:递归一定有参数);
  2. 递归出口:函数一定要能够不再调用自己,分为显示出口和隐式出口。显示出口:发现不应该调用函数自己,立马结束:return。隐式出口:函数自动运行结束,没有发现递归点。

需求:用div包裹结构里面的数据:name的数据

// data
let data=[
    {
"name": "广东",
"children": [
        {
"name": "广州",
"children": [
            {
"name": "越秀"
            },
            {
"name": "天河",
"children": [
                {
"name": "吉山"
                }
                ]
            }
            ]
        },
        {
"name": "深圳",
"children": [
            {
"name": "南山"
            }
            ]
        }
        ]
    }
]

不使用递归的代码:

data.forEach(function(item){
document.querySelector("body").innerHTML+=`<div>${item.name}</div>`
if(item.children){
item.children.forEach(function(item){
document.querySelector("body").innerHTML+=`<div>${item.name}</div>`
if(item.children){
item.children.forEach(function(item){
document.querySelector("body").innerHTML+=`<div>${item.name}</div>`
if(item.children){
item.children.forEach(function(item){
document.querySelector("body").innerHTML+=`<div>${item.name}</div>`
                            })
                        }
                    })
                }
            })
        }
    })

使用递归的代码:

function recursion_city(data){
data.forEach(function(item){
document.querySelector("body").innerHTML+=`<div>${item. name}</div>`
if(item.children){
recursion_city(item.children)
            }
        })
    }
recursion_city(data)

jQuery

jQuery是针对DOM的操作,数据加工使用原生JS。
jQuery的使用步骤:

  1. 引入jQuery文件;
  2. 添加入口函数;
  3. 在入口函数中,调用封装好的API实现页面效果;

jQuery的入口文件

入口文件的作用是,等待文档中的标签加载完毕,不是等待所有内容加载完毕,然后再去执行入口函数的代码。
使用方式:

// 方式一
$(document).ready(function(){      });
// 方式二
 $(function(){      })

入口文件的好处:

  1. 等待文档加载完成,保证能够获取到元素;
  2. 防止全局变量污染,所有的东西都是局部;

入口函数与window.onload的差异
执行次数方面:

执行时机方面:

简写方面:

jQuery与DOM之间的转换

jQuery选择器

筛选选择器

image.png

筛选方法

特点就是,先拿到所有,再筛选出需要的元素


image

jQuery样式操作

$box.css(名字,值)

多样式操作:

$box.css({名字:值,……})

jQuery动画

属性

参数

参数1:速度,默认normal(400)
参数2:变化方式,默认曲线
参数3:回调函数,动画结束调用

上一篇下一篇

猜你喜欢

热点阅读