JavaScript之入门学习风云(6)

一、正则表达式

1.1 元字符

  1. \d 一位数字 (0-9)
  2. \D一位非数字
  3. \s 1位空白 (空格 缩进 换行)
  4. \S 1位 非空白
  5. \w 一位字母 数字 下划线
  6. \W 一位非字幕数字下划线
  7. .(点)任意内容 (换行不算)
  8. .\ 转义字符

1.2 边界符

  1. ^ 开头符号
  2. $ 结尾符号
var set = /^abc$///表示前后必须为abc
var ret = /^a/dc$///表示前面必须是a 中间必须包含一位数字,最后必须是c
console.log(set.test("sada"))

1.3 限定符

  1. * 0~多次
  2. + 1~多次
  3. {n} 指定n个
  4. {n,} >=n个
var ret = /abc{2} //表示出现a,b,c,c这几个元素

1.4 特殊符号

  1. ()标是一个整体的意思
var ret = /^(abc){2}$/ //表示a b  c都要出现两次
  1. | 或的意思:表示的是左右两边随便的一边的整体
  2. [] :表示包含[]里面任意一位一样的元素就算对
  3. [^]:表示包含[]里面不包含任意一位一样的元素就算对

2. 捕获exec

补捉先满足条件的内容,返回值为数组
var a =/asdas/g //会让test勤劳起来,不会再次从首字母开始查询满足的条件
var b = /asdas/i //表示其在查询 的时候不会分大小写进行查询

  var time = "time is 2022.1.3 12:20:op"
        var newtime = /\d{2}:\d{2}/
        console.log(newtime.exec(time))

2.1正则表达式的特性

1.懒惰, 解决 使用全局标识符g
2.贪婪 : 它会将占用所有可以用到的条件,比如说:叫你拿3~5个,他必须要拿5个
3.非贪婪 加问号 var reg= /\d{1,4}?/

2.2 正则与字符串的方法

解释:

1.replace 因为replace在进行替换的时候只能选中靠前面的所要替换掉的内容,现在我们可以通过正则表达式,来选取全部的所要的元素

var str = 'dasdwaxd'
var newstr = str.replace(/a/g,"k")//这就是可以加个g就表示是全局的变量,就可以替换所有的"a"元素了
  1. search 他不能用上述方法

  2. match捕获内容

var datestr
"time is from 2029-01-01 12:20:20 to 229-11-01
12:20:20"

console.log(datestr.match(/(\d[4})-(\d[1,2))-(\d[1,2))/g))

3. this指向

3.1 初识this

  1. this是一个对象
  2. 谁调用this,this就是谁
  3. 函数调用的事件this

① 全局作用下,this指向的是window;
② 函数独立调用时,函数内部的this也指向window
③ 被嵌套的函数独立调用时,this默认指向了window

全局

 function test(){
            console.log(this);
        }
        console.log(this);

对象:

  box.onclick = function(){
            console.log(this);
        }

3.2 改用this

  1. call
  2. apply
  3. bind
3.2.1 call

call 执行函数,并改变this执行为函数的第一个参数支持多个参数
call() 方法的第一个参数必须是指定的对象,然后方法的原参数,挨个放在后面。
(1)第一个参数:传入该函数this执行的对象,传入什么强制指向什么;
(2)第二个参数开始:将原函数的参数往后顺延一位

function fun() {
    console.log(this);  // 原来的函数this指向的是 Window
}
fun();
 
function fun(a, b) {
    console.log(this); // this指向了输入的 字符串call
    console.log(a + b);
}
//使用call() 方法改变this指向,此时第一个参数是 字符串call,那么就会指向字符串call
fun.call('call', 2, 3)  // 后面的参数就是原来函数自带的实参
3.1.2 apply

apply 执行函数, 并改变this执行为函数的第一个参数两个参数, 第二个参数是一个数组
apply() 方法的第一个参数是指定的对象,方法的原参数,统一放在第二个数组参数中。
(1)第一个参数:传入该函数this执行的对象,传入什么强制指向什么;
(2)第二个参数开始:将原函数的参数放在一个数组中

function fun() {
    console.log(this);  // 原来的函数this指向的是 Window
}
fun();
 
function fun(a, b) {
    console.log(this); // this指向了输入的 字符串apply
    console.log(a + b);
}
//使用apply() 方法改变this指向,此时第一个参数是 字符串apply,那么就会指向字符串apply
fun.apply('apply', [2, 3])  // 原函数的参数要以数组的形式呈现
3.1.3 bind

bind() 方法的用法和call()一样,直接运行方法,需要注意的是:bind返回新的方法,需要重新调用

bind 改变this指向为函数的第一个参数,不会自动执行函数/支持多个参数

function fun() {
    console.log(this);  // 原来的函数this指向的是 Window
}
fun();
 
function fun(a, b) {
    console.log(this); // this指向了输入的 字符串bind
    console.log(a + b);
}
//使用bind() 方法改变this指向,此时第一个参数是 字符串bind,那么就会指向字符串bind
let c = fun.bind('bind', 2, 3);
c(); // 返回新的方法,需要重新调用
// 也可以使用下面两种方法进行调用
// fun.bind('bind', 2, 3)();
// fun.bind('bind')(2, 3);

四、ES6

4.1 ES6定义变量

增加了letconst

let与var区别

  1. 必须先定义才能够使用
  2. 变量重名会报错
  3. 块级作用域,在块级里面定义的变量在外部不可利用,有助于防止变量冲突

letconst的去别

let是一个定义变量的,而const是定义常量的
const定义的时候必须赋值,因为const定义过后的常量不能够改变

let 的 暂存性死亡:

  1. 只要我在本代码块内声明了 i,那就只能使用本代码块内声明的 i,哪怕在我定义之前使用了i也不能使用外边的i(霸道)
  2. let、const不存在变量提升(这也就导致程序会报错,而不输出undefined)

示范:

let i = 0
{//这就是一个块的起始
	console,log(i)  
	let i = 1
}//块的结束

这样会使浏览器报错

4.2 箭头函数

对于之前函数的差别

  1. 如果形参只有一个,则小括号可以省略;

  2. 函数体如果只有一条语句,则花括号可以省略,并省略return,函数的返回值为该条语句的执行结果;

  3. 箭头函数 this 指向声明时所在作用域下 this 的值;

  4. 箭头函数不能作为构造函数实例化;

  5. 不能使用 arguments;(一个特殊的数组,arguements[0]=1,可以取0,1,2)

const multiply = num => num * num; ==>const multiply = function (num) { return num * num; };他们之间是相等价的

如果返回的结果是对象,则需要配上 ()

const func = val => ({ value: val });

不适合的场景

1、对象的方法:

const obj = {
    x: 1,
    print: () => {
        console.log(this === window); // => true
        console.log(this.x); // undefined
    }
};

obj.print();

print 方法用了箭头函数,其内部的 this 指向的还是上下文 window,上下文中并没有定义 x,所以 this.x 输出为 undefined。

但是我们可以利用这个规则,制作返回上个函数内部进行的函数的再次调用

4.3 结构赋值

语法:

数组: let [a] =[1]   [变量名]:变量名可随意
对象: let {name} = {name}  {变量名}:变量名必须是对象中的属性名
  1. 数组:
按顺序: let [a,b,c] = [1,2,3]; console.log(a,b,c); //1,2,3
打乱顺序: let [b,a,c] = [1,2,3]; console.log(a,b,c); //2,1,3
 数组的是按照位置来进行结构的,所以与变量名字无关
let [a, [b,c], d] = [1, [2, 3], 4];
console.log(a,b,c,d)
//1,2,3,4
//结构和位置一一对应就行了.

  1. 对象:
按顺序: let {name,sex} = {name:"fanfusuzi",sex:"man"}; console.log(name,sex); //fanfusuzi,man
打乱顺序: let {sex,name} = {name:"fanfusuzi",sex:"man"}; console.log(sex,name); //man,fanfusuzi
 对象是按照属性名字进行结构的,所以与变量的位置无关
不存在的属性名: let {name,age} = {name:"fanfusuzi",sex:"man"}; console.log(name,age); //fanfusuzi,undefined
  1. 重命名(先取再重命名)
    数组:我们上面说过,数组解构的时候只要注意位置对应就行了,名称啥的无所谓,你喜欢叫什么变量名就什么变量名
    对象:对象解构的时候是要属性名对应才能取到值.但是没有说取到值之后不能重命名啊.一定要取到值之后在命名
let {name:myName,age} ={name:'ning',age:18}
//这里name:myName的意思是:取到name属性值,冒号后面的变量名没有花括号,意思是把我取到的值交给冒号后面的变量名,即'myName'.相当于把name变量重命名为myName
/**而student:{name},同样是'属性名:'意思一样,取里面对应的属性,冒号后面还有花括号,所以再解构,取student里面的name属性/
console.log(name,myName,age)
//undefined,ning,18

4.4 展开运算符

  1. 对于数组:
var arr = [1,2,3]
 // 复制一个数组
      let arr2=[...arr]
      arr2.push(4);
      
      // 并且不会对arr造成影响
      console.log("arr",arr);
      console.log("arr2",arr2);
      
      
      // 连接数组
      let arr3=[...arr,...arr2] 
      console.log(arr3);
  1. 对于对象的使用
      var obj1 = { foo: 'yuan', x: 42 };
      var obj2 = { foo: 'li', y: 13 };
    
      // 克隆对象一定要加上{}
      var clonedObj = { ...obj1 };
      console.log("克隆后的对象",clonedObj);
      
      // 同样的修改复制后的并不会影响原来的对象
      clonedObj.foo="ss"
      console.log("clonedObj",clonedObj);
      console.log("obj1",clonedObj);
    
      
      // 合并后的对象:
      var mergedObj = { ...obj1, ...obj2}
      console.log("合并后的对象",mergedObj);
      
     
      // 当然也可以在合并时添加新的属性
      var mergedObj = { ...obj1, ...obj2,address:"上海"}
      console.log("合并后的对象",mergedObj)

4.5 ES6模块化语法

模块化解决问题: 1.私密不漏2.重名不怕3.依赖不乱

  1. 只导出一次(exrepot defause )
    注意:只能导出一次,多了就会报错
  2. import 任意名称 from ‘模块标识符’
// import-default.js
import customName from './export-default';
customName(); // 'foo'

  1. .按需导入导出: export 按需导出的成员
/** 定义模块 math.js **/
var basicNum = 0;
var add = function (a, b) {
    return a + b;
};
export { basicNum, add };

  1. 按需导入: import { s1 } from ‘模块标识符’

可以通过as 关键字来更改变量名。

/** 引用模块**/
import { basicNum, add } from './math';
function test(ele) {
    ele.textContent = add(99 + basicNum);
}

5.1 初识面向对象

  1. 首先,我们要明确,面向对象不是语法,是一个思想,是一种 编程模式面向: 面 (脸) ,向 (朝着)
  2. 面向过程: 脸朝着过程 =》关注着过程的编程模式面向对象:
  3. 脸朝着对象=》关注着对象的编程模式实现一个效果
  4. 在面向过程的时候,我们要关注每一个元素,每一个元素之间的关系,顺序,。在面向过程的时候,我们要关注的就是找到一个对象来帮我做这个事情,我等待结果
  5. 我们以前的编程思想是,每一个功能,都按照需求一步一步的逐步完成

5.2 创建对象函数的方式

  1. 工厂函数:
 function createObject(name){
            var obj = {}
            obj.name = name
            onj.matical = []
            return obj
        }
        var obj1 = createObject('shaokao')
  1. 自定义函数
            function createObject(name){
                this.name = name
                this.martical = []
                this.coke = function(){
                     
                }
            }

            var obj2=new createObject("第三次")

5.3 面向对象原型

概念:

在典型的 OOP 的语言中(如 Java),都存在类的概念,类就是对象的模板,对象就是类的实例,但在 ES6之前, JS 中并没用引入类的概念。

ES6, 全称 ECMAScript 6.0 ,2015.06 发版。但是目前浏览器的 JavaScript 是 ES5
版本,大多数高版本的浏览器也支持 ES6,不过只实现了 ES6 的部分特性和功能。

在 ES6之前 ,对象不是基于类创建的,而是用一种称为构造函数的特殊函数来定义对象和它们的特征。

2.对象原型 __ proto _

  • 对象都会有一个属性__proto__指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在。
  • _proto_对象原型和原型对象prototype是等价的。
  • _proto_对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype

5.4 class类

cLass createobj {
//构造器函数
constructor( name){
this.name =name
}
}


5.5 继承

构造函数继承

function student(name ,age,classroom){
			Person.ca11(this,name , age)
			this.classroom = classroom
			}

原型继承

student.prototype = new Person0

组合继承
构造函数继承+原型继承

function Person(name , age){
		this.name = name
		this.age = age
		}

5.6 ES6继承

  //夫类
        class Person{
            constructor(name,age){
                this.name = name
                this.age = age
            }
            say(){
                console.log("hello")
            }
        }

        //extends继承
        class Student extends Person{
            constructor(name,age,grad){
                super(name,age) //super相当于Person.call(this,name,age).而且super必须写到constructor里面的第一行
                this.grad = grad
            }
            //直接可以改变Parson里面的方法使自己使用
            
            say(){
                super.say()//调用父元素的say()使其不会被覆盖
                document.write("bjsad")//修改say()方法,将其覆盖,若加上super就不会被覆盖
            }
        }

        var obj = new Student("asd",100,100)
        console.log(obj.grad)
        obj.say()

6.初识前后端交互

6.1 ajax

AJAX 的优势

1.不需要插件的支持,原生js 就可以使用
2.用户体验好(不需要刷新页面就可以更新数据)
3.减轻服务端和带宽的负担
4.缺点: 搜索引擎的支持度不够,因为数据都不在页面上,搜索引擎搜索不到

AJAX 的使用

  • 在js 中有内置的构造函数来创建 aiax 对象
  • 创建 ajax 对象以后,我们就使用 ajax 对象的方法去发送请求和接受响应

创建步骤:

  1. 创建XHR ==》new XMLHTTPRequest()
  2. 配置open(请求方式,请求地址,是否同步)
  3. send发出
  4. 接受数据,创造一个事件

ajax状态码 200ok 404error

  • ajax 状态码-xhr.readystate
  • 是用来表示一个 ajax 请求的全部过程中的某一个状态
  • readystate === 0 :表示未初始化完成,也就是open方法还没有执行
  • readyState === 1:表示配置信息已经完成,也就是执行完open 之后
  • readystate === 2 : 表示send 方法已经执行完成
  • readystate === 3 :表示正在解析响应内容o
  • readystate === 4 :表示响应内容已经解析完毕,可以在客户端使用了
  • 这个时候我们就会发现,当一个 ax请求的全部过程中,只有当 r
  • eadystate === 4 的时候,我们才可以正常使用服务端给我们的数据 所以,配合 http 状态码为 200 ~ 299
  • 一个ajax 对象中有一个成员叫做 xhr.status这个成员就是记录本次请求的 http
  • 状态码的两个条件都满足的时候,才是本次请求正常完成
  var xhr = new XMLHttpRequest()
      // ip:js%E5%AE%9E%E6%88%98%E7%BB%83%E4%B9%A0
        xhr.open("GET","http://127.0.0.1:5500/js%E5%AE%9E%E6%88%98%E7%BB%83%E4%B9%A0/01.text")
        xhr.send()

        //当后端与前端接上头后执行该函数
        xhr.onreadystatechange = function(){
            // console.log("edkw");

            if(xhr.readyState===4 &&xhr.status === 200){
                console.log("此时已经加载完毕");
            }else if(xhr.readyState === 4 && xhr.status===404){
                console.log("没有找到这个对象");
            }
        }
        //两种区别为:onload判断一次,而onreadstatechange判断四次
        // xhr.onload = function(){
        //     // console.log(xhr.responseText)
        //     if(xhr.status==200){
        //         document.write(xhr.responseText)
        //     }else if(xhr.status===404){
        //         console.error("没有找到这个页面")
        //         // location.href ="404.html
        //     }
        // }

案例:ajax

script部分

<ul id="malist"></ul>
    <button id="btn">lisy</button>
    <script>
        btn.onclick = function(){
            var xhr = new XMLHttpRequest()
            // ip:js%E5%AE%9E%E6%88%98%E7%BB%83%E4%B9%A0
                xhr.open("GET","http://127.0.0.1:5500/js%E5%AE%9E%E6%88%98%E7%BB%83%E4%B9%A0/data.json")
                xhr.send()

                //当后端与前端接上头后执行该函数
                xhr.onreadystatechange = function(){
                    // console.log("edkw");

                    if(xhr.readyState===4 && xhr.status === 200){
                        console.log("此时已经加载完毕");
                        var jsondata = JSON.parse(xhr.responseText)
                        rader(jsondata)
                    }else if(xhr.readyState === 4 && xhr.status===404){
                        console.log("没有找到这个对象");
                    }
                }
            function rader(jsondata){
                var html = jsondata.data.list.map(item=>`
                    <li>
                        <img src="${item.imageUrl}"/>
                        <div>${item.name}</div>    
                    </li>
                `)
                malist.innerHTML = html.join('')
            }
        }    

json部分:

{
    "data":{
        "list":[
            {
                "namne":"1111",
                "imageUrl":"https://ts1.cn.mm.bing.net/th?id=ORMS.7bf3e9347df69e68f66692e0f32f7bc9&pid=Wdp&w=612&h=304&qlt=90&c=1&rs=1&dpr=1.25&p=0"
                
            },
            {
                "namne":"1111",
                "imageUrl":"https://ts1.cn.mm.bing.net/th?id=ORMS.7bf3e9347df69e68f66692e0f32f7bc9&pid=Wdp&w=612&h=304&qlt=90&c=1&rs=1&dpr=1.25&p=0"
                
            },
            {
                "namne":"1111",
                "imageUrl":"https://ts1.cn.mm.bing.net/th?id=ORMS.7bf3e9347df69e68f66692e0f32f7bc9&pid=Wdp&w=612&h=304&qlt=90&c=1&rs=1&dpr=1.25&p=0"
                
            }
        ]
    }
}

6.2 ajax同步异步

里面的第三个值

xhr.open("GET","http://127.0.0.1:5500/js%E5%AE%9E%E6%88%98%E7%BB%83%E4%B9%A0/data.json",true)

表示异步请求true :表示会进行后面的函数,等返回值调回来的时候跟着回去
false表示同步请求 ::表示异步,要等到返回的数据回来过后才会执行后面的代码,所以容易造成数据的堵塞

6.3 ajax的请求方式

get 偏向获取数据
post 偏向提交数据
put 偏向更新(全部) {name:“kerwin”,age:100]delete 偏向删除信息
patch 偏向部分修改

  1. get

xhr.open('GET','http://127.0.0.1:8080/server?a=100&b=200');

  1. post

xhr.open('POST',"http://127.0.0.1:8080/server")

  1. json
const xhr = new XMLHttpRequest();
//设置响应体数据类型
xhr.responseType='json'
xhr.open('GET','http://127.0.0.1:8080/server-json')
xhr.send()
xhr.onreadystatechange=function(){
    if(xhr.readyState===4){
        if(xhr.status >= 200 && xhr.status < 300){
 
         // 手动修改
         // let data = JSON.parse(xhr.response)
         // console.log(data);
 
         //自动修改  在上边设置响应体数据类型
         console.log(xhr.response);
         
          }
     }
} 

6.4 ajax封装

 ajax({
        ur1:"http://1ocalhost:3000/users",
        method:"GET",
        async:true ,
        data:{
        username : "kerwin",
        password:"123"
        },
        headers:{},
        success:function(res){
            console.log(res)
        }
        error:function(err){
            console.log(err)
        }
    })

6.6 回调地狱问题

·当一个回调函数嵌套一个回调函数的时候·就会出现一个嵌套结构
·当嵌套的多了就会出现回调地狱的情况·比如我们发送三个ajax请求
.第一个正常发送
.第二个请求需要第一个请求的结果中的某一个值作为参数
.第三个请求需要第二个请求的结果中的某一个值作为参数

6.8 Promise封装ajax

<script>
封装 ajax
  function ajax(options) {
    let defaultoptions = {
      url: "",
      method: "GET",
      async: true,
      data: {},
      headers: {
        "content-type":"application/x-www-form-urlencoded"
      },
      success: function () { },
      error: function () { }
    }
    let { url, method, async, data, headers, success, error } = {
      ...defaultoptions,
      ...options
    }
    </script>

6.10 fetch

用于发起获取资源的请求。它返回一个 promise,这个 promise 会在请求响应后被 resolve,并传回 Response 对象。当遇到网络错误时,fetch() 返回的 promise 会被 reject,并传回 TypeError。成功的 fetch() 检查不仅要包括 promise 被 resolve,还要包括 Response.ok 属性为 true。HTTP 404 状态并不被认为是网络错误。

`

var username = "kerwin"
fetch(` http:// localhost:3000/users111?username=$ {username} `)
.then((res)=>{
console. log(res)
if(res.ok){
return res.json()
}else{
//拒绝
return Promise.reject(
}

cookie

<script>
       //cookie 本地存储
       // 存cookie

       savebtn.onclick = function(){
           //路径设置
        //    document.cookie = "username=xiaoming;path=/155-cookie/aaa"
            document.cookie = "age=18"
       
            //过期时间设置
            var date = new Date()
            date.setMinutes(date.getMinutes()+10)
            document.cookie = `username=kerwin;expires=${date.toUTCString()}`
        }

        getbtn.onclick = function(){
            console.log(getCookie("age"))
        }

        function getCookie(key){
            var str = document.cookie
            var arr = str.split("; ")
            // console.log(arr)
            var obj = {}
            for(var i=0;i<arr.length;i++){
                var subArr = arr[i].split("=")
                // console.log(subArr)
                obj[subArr[0]] = subArr[1]
            }

            // console.log(obj)
            return obj[key]
        }

        delbtn.onclick = function(){
            var date = new Date()
            date.setMinutes(date.getMinutes()-1)
            document.cookie = `username=111;expires=${date.toUTCString()}`
            document.cookie = `age=111;expires=${date.toUTCString()}`
        }
</script>

josnp

注意:

  1. 后端接口形式必须**(),需要后端配合
  2. jsonp 缺点
    onload 删除sciprt标签
    只能get请求,不能post put delete
mybtn.onclick = function(){
var oscript = document.createElement( "script")
oscript.src="01.txt”//未来地址
document.body . appendchild(oscript)
}


闭包

函数内部返回一个函数,被外界所引用。
这个内部函数就不会被销毁回收。
内部函数所用到的外部函数的变量也不会被销毁

闭包案例

  1. 求索引值下标
    法一:(闭包)
var oli = document.querySelectorAl1("li")
        for (var i = 0; i < oli.length; i++) {
            oli[i].onclick = (function (index) {
                return function () {
                    console.log(11111, index)
                }
            })(i) //匿名自执行函数
        }

法二:(ES6)

 var oli = document.querySelectorAl1("li")
        for(let i=0;i<oli.length;i++){
            oli[i].onclick =function(){
                console.log(i)
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值