JS基础知识

JS基础知识

一、组成部分

1、组成部分

① BOM
② DOM:js操作文档流变化的属性和方法
③ ECMAScript:js 的书写语法和书写规则

2、书写位置

① 行内式:书写在href属性上
		<a href='javascript': 代码;></a>
	    非a标签--书写在行为属性上
		<div onclick="alert('hello')">点我一下</div>
② 内嵌式:把代码书写在一个script标签上(不需要任何依赖行为,打开页面就会执行)
③ 外链式:把代码书写在一个 .js 文件中 (使用script的src属性来引入)

二、变量

1、显示方式

① 在浏览器弹窗显示 num 的值:alert(num)
② 在控制台打印 num 的值:console.log(num)
③ 直接在页面输出 num 的值:document.write(num)

2、变量类型

① 基本数据类型:String、Boolean、Number、Null、Undefined、Symbol、BigInt,存储在栈中,占据空间小,属于被频繁使用的数据,所有基本数据类型都占 8 个字节
② 引用数据类型:Array、Object、Function,存储在堆中,占据空间大,在栈中存储了引用数据类型的指针,指向堆中该实体的引用地址

3、数据类型的转换

① 转数值
(1)Number(): Number(要转换的内容)
(2)ParseInt(): ParseInt(要转换的内容)
(3)ParseFloat(): ParseFloat(要转换的内容)
  • 不是数字的会转换成 NaN(Not a number)
② 转字符串
(1)String(): String(要转换的内容)
(2)toString(): toString(要转换的内容)
③ 转布尔值
(1)Boolean(): Boolean(要转换的内容)

4、运算符

① 等于: == (数值相等就可以)
② 全等于: === (数值和类型都必须相等)

三、函数

1、基础函数

定义
function fn(){

		}
调用 fn()

2、递归函数

// 一个函数调用了自身,并说明终止条件
function(n){
		if(n === 1) return 1;
		return n * f(n-1);
}

3、作用域

① 全局作用域:一个页面就是一个作用域
② 局部作用域:只有函数,生成的私有作用域

4、对象数据类型

var obj = {}

5、数组

① 改变原数组的方法

1、push(): 末尾添加,返回长度,相当于进栈操作
2、unshift(): 首部添加,返回数组长度
3、pop() : 尾部删除,返回删除的元素
4、shift() : 首部删除,返回删除的元素
5、splice(index,length,新增元素1,新增元素2…) :表示从index开始删除length个元素,并从index开始新增元素1-N,返回被删除的元素 组成的数组
6、sort():返回排序后的数组,return a-b 是升序
7、reverse():返回颠倒后的数组
8、fill(value, start, end):用静态值填充数组指定元素,如果未指定开始和结束位置,则填充所有位置

② 返回新数组的方法

1、concat(): 合并两个或多个数组
2、slice(start,end): 剪切,不传参数相当于复制一份数组
3、filter(function(value,index,arr){}) :过滤,value是指,index表示索引
4、map() :格式化,返回的是布尔值

③ reduce方法
reduce(function(previousValue, currentValue, index, array){
				return previousValue + currentValue
			})
// filter 方法实例
var a = [1,2,3,4,11]
// 第一个参数为一个方法,有三个参数,current:当前值 index:当前值下标 array:这个数组对象
var b = a.filter(function(current,index,array){
    return current < 10
})
console.log(b) // [1,2,3,4]
console.log(a) // [1,2,3,4,11]

6、字符串

1、charAt(): 按照索引获取字符
2、toUpperCase(): 转大写
3、split(): 切割字符串
4、trim(): 去掉首尾空格
5、slice(): 截取字符串子串

7、数字的常用方法

1、random(): 随机产生 0~1 之间的数组
2、round(): 四舍五入取整

8、forEach的用法

var arr = [1,2,3,4]
sum = 0
// value: 数组的内容
// index: 数组的索引
// arr: 数组本身
arr.forEach(function(value,index,arr){
	arr[index] == value  // true
	sum += value
})
console.log(sum)   // 10

四、BOM和DOM

1、BOM

① BOM 是浏览器对象模型
② window 是浏览器的内置中的全局对象,所学习的所有 web API 都是基于 window 对象实现的
③ window 对象下包含了 navigator、location、history、document、screen 五个属性
④ document 是实现 DOM 的基础,依附于 window 属性
注:依附于 window 对象所有的属性和方法,使用时可以省略 window

2、定时器

① 间隔定时器:没个一段时间重复执行

setInterval(函数,时间)

② 延时定时器:只执行一次

setTimeout(函数,时间)

③ 关闭定时器

// 关闭间隔定时器
clearInterval(定时器的返回值)

// 关闭延时定时器
clearTimeout(定时器的返回值)

3、DOM

① 获取元素的方式

1、根据选择器获取一个元素: document.querySelector(‘选择器’)
2、根据选择器获取多个元素: document.querySelectorAll(‘选择器’)

② 操作元素内容

1、获取元素文本内容:元素.innerText
2、设置元素文本内容:元素.innerText = “新内容”
3、获取元素超文本内容:元素.innerHTML
4、设置元素超文本内容:元素.innerHTML= “新内容”

③ 操作元素属性

1、获取属性:元素.getAttribute(‘属性名’)
2、设置属性:元素.setAttribute(‘属性名’,‘属性值’)
3、删除属性:元素.removeAttribute(‘属性名’)

④ 操作元素类名

1、获取类名:元素.className
2、设置类名:元素.className = “新类名”

⑤ 操作元素行内样式

1、获取样式:元素.style.样式
2、设置样式:元素.style.样式 = “样式值”

⑥ 操作节点

1、创建节点:document.createElement(“元素名称”)
2、插入节点:父节点.appendChild(子节点),把子节点插入在父节点的后面
父节点.insertBefore(子节点,哪一个子节点的前面),把子节点插入在某个子节点的前面
3、删除节点:父节点.removeChild(子节点),从父节点内删除子节点
节点.remove(),节点把自己删除

五、事件

1、事件绑定

事件绑定的三要素:① 事件源:和 做好约定
② 事件类型:约定一个什么样的行为
③ 事件处理函数: 当用户触发该行为时,执行什么代码
语法:事件源.on事件类型 = 事件处理函数

2、事件类型

在这里插入图片描述

3、事件对象

当事件触发的时候,描述该事件信息的对象数据类型

4、事件传播

① 捕获阶段:从 window 按照结构子级的顺序传递到 目标
② 目标阶段:准确触发的事件接收到行为
③ 冒泡阶段:从 目标 按照结构子级的顺序传递到 window

5、阻止事件传播

事件对象.stopPropogation()

6、事件委托

利用事件冒泡的机制,把自己的事件委托给父级的某一层

六、面向对象

1、自定义构造函数创建对象

// 构造函数会自动创建对象, 自动返回这个对象
    // 我们只需要手动想里面添加内容就可以了
    function createObj(name, age) {
      // 自动创建对象

      // 手动向对象里面添加成员
      // 这里的  this 指向当前实例(new 前面的变量)
      this.name = name
      this.age = age
      this.sayHi = function () { console.log('hello world') }
      // 自动返回对象
    }
// 构造函数在使用的时候, 需要和 new 关键字连用
// 函数内部的代码在执行的时候, 就是在向 obj1 添加了 name age 和 sayHi 三个成员
    var obj1 = new createObj('Jack', 18)

2、构造函数的使用

① 构造函数和普通函数没有区别,只是在调用的时候需要和 new 关键字连用
② 书写构造函数时,函数首字母需要大写
③ 调用的时候需要和 new 关键字连用,这样才会有 自动创建和返回对象的能力
④ 当函数名和 new 关键字连用的时候, 函数内部的 this 指向的是当前实例对象
⑤ 构造函数内部不要随便写 return,当 return 了一个基本数据类型时,相当于没写
当 return 了一个复杂数据类型时,构造函数白写

七、原型

1、原型(prototype)

① 定义: 每一个函数天生自带一个原型(prototype),是一个对象

② 构造函数也是函数,所有也会自带一个 原型(prototype)

③ 既然 prototype 是一个对象,我们就可以以一个对象的方法往 prototype 上添加一些内容

2、对象

① 定义:每一个对象,当你访问它成员的时候,如果它身上此时没有这个属性,会自动往其所属构造函数的 prototype 上去查找

② 自定义构造函数创建的对象也是对象, 当你访问某一个成员的时候
=> 如果没有, 也会自动去所属构造函数的原型上查找
=> 哪一个构造函数创建的对象, 这个对象就属于哪一个构造函数
=> 因为构造函数在创建对象的过程, 我们起名为 实例化 的过程
-> 创建出来的对象叫做这个构造函数的一个 实例化对象

 function Person() {}
    Person.prototype.sayHi = function () { console.log('我是 Person 原型上的方法') }
    console.log(Person.prototype)
    // 创建一个实例化对象
    // 因为 p1 是 Person 实例化出来的对象
    // p1 就是属于 Person 这个构造函数的
    // 当你访问 p1 的 sayHi 成员的时候, p1 自己是没有的
    // 会自动去 Person 的 原型(prototype) 上查找
    var p1 = new Person()
    console.log(p1)
    p1.sayHi()

    // 创建第二个实例化对象
    // 因为 p2 也是 Person 的实例化对象
    // p2 没有 sayHi 成员, 也会自动去 Person 的原型上查找
    var p2 = new Person()
    console.log(p2)
    p2.sayHi()

    /*
      p1 的 sayHi 方法和 p2 的 sayHi 方法都是使用的 Person 构造函数的原型上的方法
      我只要向 Person 的原型上添加一些方法
      所有的 Person 的每一个实例都可以使用
      并且使用的都是同一个函数, 不会出现浪费空间的行为
    */
   console.log(p1.sayHi === p2.sayHi) // true 说明是一个函数

注:原型对象就相当于一个公共区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中

3、原型链

① 实例对象身上的 proto 指向谁?
所属构造函数的 prototype 对象

② Person.prototype 的 proto 指向谁?
1)Person.prototype的所属构造函数是谁
2)Person.prototype 是一个对象
3)在 js 中,所有对象的所属构造函数都是 Object
4)Person.prototype 的 proto 指向的是 Object 的 prototype 对象

③ Person 的 proto 指向谁?
1)函数本身也是一个对象,就会有 proto 属性
2)在 js 中,所有函数的所属构造函数都是 Function 的实例
3)所有指向的是 Function 的 prototype 对象

④ Object.prototype 的 proto 指向谁?
注意:Object.prototype 在 JS 内叫做顶级原型,不存在有 proto
Object.prototype 的 proto 指向 null

⑤ Object 的 proto 指向谁?
1)Object 是一个内置构造函数,同时也是一个函数,也是一个对象
2) 在 JS 内,所有的函数都是属于内置构造函数 Function 的实例
3)Object 也是 Function 的实例
4) Object.proto 指向的是 Function.prototype

⑥ Function.prototype 的 proto 指向谁?
1)在 JS 内所有的 Object 类型都是属于 Object 这个内置的构造函数
2)Function.prototype 是属于 Object 这个内置的构造函数的
3)Function.prototype 的 proto 属于 Object.prototype

⑦ Function 的 proto 指向谁?
1) Function 是一个内置构造函数,也是一个构造函数
2) 在 JS 内,所有的函数都是属于内置构造函数 Function 的实例
3) Function是自己的构造函数,也是自己的实例对象
4) Function 所属的构造函数是 Function

注:原型链,用下划线 proto 串起来的对象链装结构,每一个对象数据类型,都有一个属于自己的原型链

⑧ 对象访问机制:
1) 当你需要访问对象成员的时候,首先在自己身上查找,如果有则直接使用
2)如果没有,会自动去所属构造函数的原型对象上去查找
3)如果还没有,回去 proto 上查找
4)直到 Object.ptototype 都没有,那么返回 undefined
在这里插入图片描述

八、ES6

1、定义的变量

① var 可以进行预解析,let 和 const 不能

② var 可以重复变量名,let 和 const 不能

③ var 可以做越过块级作用域,而 let 和 const 不能
块级作用域:每一个 {} 都是一个代码块

④ let 定义时可以不赋值(块级作用域),而 const 必须赋值(块级作用域)

⑤ const 一旦定义好,不能被修改值

2、箭头函数

getName()=>{
	// 函数体
}

① 当函数只有一个形参的时候,可以省略 ()

② 箭头函数某些时候可以省略 {}
1)当你的代码只有一句话的时候
2)并且自动会把这一句话当做返回值

③ 箭头函数之内没有 arguments(任意个参数)

④ 箭头函数没有 this ,它的 this 就是全局的 this

3、模板字符串

var str = `hello`

// 可以换行书写
// 可以直接在字符串内解析变量 ${变量}

4、展开运算符

  /*
            展开运算符:
                ① ...
                ② 作用:展开数组的 [],或者对象的 {}
        
        */

        var arr = [10,2,3,5,2,3]
        console.log(...arr)

        // 作用1:合并数组
        var arr1 = [1,2,3]
        var arr2 = [4,5,6]
        var arr3 = [7,8,9]
        var arr4 = [10,20,30]

        var arr5 = [...arr1,...arr2,...arr3,...arr4]
        console.log(...arr5)

        // 作用2:给函数传递参数
        var max = Math.max(...arr5)
        console.log(max)

        // 展开对象
        var obj = {name:'Rose',age:18}

        console.log(obj)
        // 作用一:用来复制对象,主要展开成员的顺序,在有相同成员的时候

        var obj2 = {
            gender:'女',
            ...obj
        }
        console.log(obj2)

5、类语法

 类语法:
            class 类名{
                constructor(){

                }

                直接书写原型上的方法即可

            }

            1、必须和 new 关键字连用
        */
       function Person(name,age){
            this.name = name
            this.age = age
       }

       Person.prototype.sayhi = function(){
           console.log('hello')
       }

    //    书写静态属性和静态方法
       Person.sex = '男'
       Person.go = function(){
            console.log('running...')
       }

    // 构造函数本质上还是一个函数,可以不和 new 连用

    // 类的书写
    class Animal{
        constructor(name,age){
            this.name = name
            this.age = age
        }

        // 直接书写原型上的方法
        sayhi(){
            console.log('hello,world')
        }

        // 书写静态属性和方法必须加上 static,不能通过实例对象来访问
        static gender = '女'

        static gogo = function(){
            console.log('跑起来')
        }
    }

    var a1 = new Animal('dog',19)
    console.log(a1)

    Animal.gogo()

九、前后端交互

1、简单的 ajax 请求:实现网页与服务器的交互

	/*
      第一次尝试 ajax
    */

    // 1. 创建一个 ajax 对象
    var xhr = new XMLHttpRequest()

    // 2. 配置本次的请求信息
    // 请求方式: 按照接口文档来进行书写
    // 请求地址: 按照接口文档来进行书写
    // 是否异步: 默认是 true 表示异步请求, 选填为 false, 表示同步请求
    xhr.open('GET', 'http://localhost:8888/test/first', true)

    // 3. 配置一个请求完成后触发的事件
    // 请求完整: 本次请求发送出去, 服务器接收到了我们的请求, 并且服务器返回的信息已经回到了浏览器
    xhr.onload = function () {
      // 如何拿到后端返回的信息
      // 语法: xhr.responseText
      console.log(xhr.responseText)
    }

    // 4. 把本次请求发送出去
    xhr.send()

2、测试 ajax 请求

	/*
      第二次测试 ajax
    */

    // 1. 创建ajax 对象
    var xhr = new XMLHttpRequest()

    // 2. 配置本次的请求信息
    xhr.open('GET', 'http://localhost:8888/test/second', true)

    // 3. 配置请求完成的事件
    xhr.onload = function () {
      // 当后端返回的是 json 格式字符串的时候, 我们需要进行单独的解析
      // 语法: JSON.parse(json格式字符串)
      // 返回值: 解析好的 js 格式的数据
      var res = JSON.parse(xhr.responseText)
      console.log(res)
    }

    // 4. 发送出去
    xhr.send()

3、请求方式

① get: 通常是获取服务器资源,从服务器获取 HTML 文件等等

②post: 通常是向服务器提交资源,如注册用户等等

十、作用域

1、变量声明提前:使用 var 声明的变量,会在所有代码执行前声明(但不会被赋值

2、函数声明提前:

		① 使用函数声明创建的函数 function 函数(){},它会在所有的代码之前就被创建,所以我们可以在函数声明前调用函数
		
	    ② 使用表达式创建的函数,不会声明提前,所以不能在声明前进行调用

3、函数作用域

		① 调用函数时创建函数作用域,函数执行完毕以后,**函数作用域销毁**
		
		② 每调用一次函数就会创建一个新的函数作用域,他们之间是**相互独立的**
		
		③ 在函数作用域当中可以访问到全局作用域的变量,在全局作用域中访问不到函数作用作用域的变量
		
		④ 当函数作用域操作一个变量时,如果自身作用域没有,则会在上一级寻找,有则直接使用,没有的话一级级往上找,找到不的话就 报错
		
		⑤ 在函数中要访问全局变量可以使用 **Windows 对象**

4、在函数作用域也有声明提前的特性:

		① 使用 var 关键字声明的变量,会在函数中所有的代表执行前被声明 
		
		② 函数声明也会在所有的代码执行前执行
		
		③ 在函数中,不使用 var 声明的变量都会成为全局变量

5、静态成员与实例成员

		① 静态成员:在构造函数本身上添加的成员,不能通过对象来访问
		
		② 实例成员:通过构造函数内部 this 添加的成员,只能通过实例对象来访问

十一、this

1、this 的指向

		① 以函数的形式调用时,this 永远指向的是 window
		
		② 以方法的形式调用时,this 指向的就是调用方法的那个对象
		
		③ 当以构造函数的形式调用时,this 就是新创建的对象

		④ 对象不能形成自己的作用域,其作用域为全局作用域

2、使用工厂模式创建对象

		function createPerson(name,age){
            // 创建一个新对象
            var obj = new Object()

            // 向对象中添加属性
            obj.name = name
            obj.age = age

            return obj
        }

        var obj1 = createPerson("林俊杰",'25')
        var obj2 = createPerson("周杰伦",'28')

3、构造函数与普通函数

		① 构造函数其实就是(首字母大写)一个普通函数,创建方式与普通函数没什么区别

		② 普通函数直接调用,而构造函数需要使用 new 关键字来调用

		③ 构造函数的执行流程:
				1)立刻创建一个新的对象
				2)将新创建的对象设置为函数中的 this,在构造函数中可以使用 this 来引用新建的对象
				3)逐渐执行函数中的代码
				4)将新建的对象作为返回值返回

4、call() 和 apply()

		① 这两个方法都是函数对象的方法,需要通过函数对象来调用
		
		② 当函数调用 call() 和 apply() 都会执行函数
		
		③ 在调用 call() 和 apply() 可以将一个对象指定为第一个参数,此时这个对象会成为函数执行时的 this
		
		④ call() 方法可以将实参在对象之后依次传递
		
		⑤ apply() 方法需要将实参封装到一个数组中统一传递

5、JSON

		① JS中的对象只有 JS 自己认识,其他语言都不认识
	
	   ② JSON 就是一个特殊格式的字符串,这个字符串可以被任意语言所识别,并且可以转换为任意语言的对象
	
	   ③ JSON在开发中主要做数据的交互
	
	   ④ JSON 和 JS 的对象格式一样,只不过 JSON 字符串中的属性名必须加 **双引号**
	
	   ⑤ JSON 分类:字符串、数值、布尔值、null、对象、数组
	
	   ⑥ 将 JSON 字符串转换为 JS 中的对象,提供了一个工具类就叫 JSON
			1) json ---> js: JSON.parse(json)
	
			2)   js ---> json: JSON.stringify(json)

十一、Promise

1、实现异步操作

const fs = require("fs")

const p = new Promise(function(resolve,reject){
    fs.readFile("one.txt",(err,data) => {
		
        if(err) reject(err)

        resolve(data)
    })
})

p.then(function(value){
	  // 成功时
    console.log(value.toString())
},function(reason){
    console.log(reason.toString())
})

2、Proxy 拦截器

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写

var proxy = new Proxy(target, handler);

Proxy 对象的所有用法,都是上面这种形式,不同的只是handler参数的写法。其中,new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。

十二、深拷贝和浅拷贝

1、深拷贝:复制真正的值,相互之间不会有影响

var obj1 = {
    a:1,
    b:2,
    arr:['暂时的记号','离开那一些','幸存者']
}

function copyObj(obj){
    if(Array.isArray(obj)){
        var new_obj = []
    }else{
        var new_obj = {}
    }

    for(var key in obj){
        if(typeof obj[key] == 'object'){
            new_obj[key] = copyObj(obj[key])
        }else{
            new_obj[key] = obj[key]
        }
    }

    return new_obj
}

console.log(copyObj(obj1))

new_obj = copyObj(obj1)

new_obj.a = '我想睡觉'
obj1.b = '我要学习'

console.log(obj1)
console.log(new_obj)

2、浅拷贝:只复制引用[地址],而没有复制真正的值,两个指向的是同一个地址,相互影响

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值