目录
JavaScript中也有对应的数据类型的划分:
-bigInt
口诀:四基两空一对象(四基本类型、两空类型、一对象类型)
- 四基:number(数值类型)、string(字符串型)、bool(布尔型)、symbol(符号类型)
- 两空:Null(空对象、空引用)、Undefined(未定义的空值)
- 一对象:object(对象类型,复杂数据,引用数据类型)
数据类型的转换:
转换为数据类型:Number、parseInt、Paserfloat
转换为字符串类型:String、toString
转换为Boolean类型:boolean
算术运算
单目运算符(一元运算符)
自增和自减运算符
比较运算符
逻辑运算符
括号运算符
逗号运算符
条件运算符
语法:
- swich(表达式1){
- case 表达式2:
- 语句:
- break
- case 表达式3:
- 语句:
- break
- case 表达式4:
- 语句:
- break
- default:
- 语句:
- }
-
- 注意:如果switch在匹配case的过程中,没有匹配成功,则会执行default中的语句
语法:
- while(表达式){
- 语句;
- ...
- }
-
- while语句的执行流程:
- 1、计算while括号中表达式的值,如果为true,执行{}中的循环体,反之则退出循环
- 注意:如果表达式计算得到的值不是布尔类型,则会进行隐式转换
-
- 注意:while语句使用时必须制定两个东西
- 1、循环控制变量
- 2、每一次循环中要更新当前的循环控制变量
- 如果缺少以上的两个东西,将会陷入死循环!
语法:
- do{
- 代码段;
- }while()
-
- 执行提醒:
- 1、上来先执行一次循环体的内容
- 2、执行完毕后,再去判断while后的表达式的值,如果值为true,则继续执行循环体,直到表达式为false
- 如果表达式为false,则直接结束循环,
4、for
语法:
- for(表达式1;表达式2;表达式3){
- 表达式4;
- }
-
- for语句的运行流程:
- 1、计算表达式1的值,对for循环进行,循环变量的定义和初始化
- 2、计算表达式2的值,如果值为true
- 3、执行循环体,进入循环,循环执行结束进入表达式4
- 4、表达式3,对循环控制变量的更新,当循环变量更新完毕,跳回表达式2;再进行流程2
函数:已经封装好了的一段可以重复调用,并且可以实现某种功能的代码块
1、封装好的
2、重复调用
3、实现某种功能或目的
方法、匿名函数、回调函数、自执行函数、构造函数、全局函数、局部函数、箭头函数...
注意:函数在不同的情况,或者说不同的环境、不同的使用中,对其称号是发生改变的!
- 无参函数
- function 函数名(){
- 函数体:
- 语句;
- 语句;
- ...
- }
-
- 有参函数
- function 函数名(形参列表){
- 函数体:
- 语句;
- 语句;
- ...
- }
函数在调用时,传参应该遵循一些规则:
1、遵循参数的顺序一致
2、遵循参数的个数一致
3、遵循参数的类型一致
简称:三一原则
函数是一个表达式,函数表达式默认的返回值是undefined
如果,需要指定返回值,请使用return语句将数据返回
语法: return 表达式
注意:函数的默认返回值是undefined
- 函数的参数传递分为两种情况
- 1、值传递
- 当函数在调用时,实参数据是基本数据类型时,这时传给形参的是值
- 当函数在运行中改变了形参是不会影响到实参变量的
-
- 2、引用(地址)传递
- 当函数在调用时,实参变量是引用数据类型时,这时传递给形参变量的就是地址量,共享一个空间
- 当函数在运行中改变了形参变量是会影响到实参变量的数据的
- 作用域:var声明的变量以及function声明的函数在声明创建的时候,其作用域就已经确定了!
-
- -全局作用域
- -函数作用域
- 作用域的作用:划分变量和函数的使用区域
-
-
-
-
- 作用域链:就在将多个作用域链进行关联,形成一个隐式的链条,通过这个链条可以访问到上级作用域
- 注意:作用域链是从里往外依次寻找,不能从外往里找
-
- 注意:全局作用域是无法访问到函数作用域中的变量,或者函数的!
- 函数作用域可以通过作用域链访问全局作用域
-
- 注意:var可以在当前的作用域声明该作用域下的变量
-
- JS的代码并不是一上来就开始解释执行,而是在执行前有一个短暂的预解析过程!
-
- 预解析中主要做以下事情:
- 1、构建全局对象
- 2、寻找当前作用域下所声明的所有var 声明变量 以及function声明的函数,将他们提前到当前作用域的最前面
-
- 只要有var就会提前
-
- 函数调用时,隐式的传入了两个参数(两个对象)
- this
- arguments用于接收存储函数调用时传入的所有实参
-
-
- 注意:arguments是一个类数组,可以通过下标访问,也有length属性
- 顶层对象:在不同的运行环境中,顶层对象是不一样的!
- window对象,就是js运行时,宿主环境中所提供的对象(浏览器)
-
- js代码在开始执行前首先它会在当前的运行环境中创建一个全局对象(global)
-
- 全局对象主要是用来保存,官方提供的原生对象,以及全局方法,全局属性、宿主环境提供的一系列对象
- 还会在解析阶段中全局作用域下的全局变量、全局函数、都作为全局对象的属性进行保存!
-
- 注意:宿主环境不同,global对象是不同的
- 浏览器(window)
- Nodejs(global)
- this关键字:当函数被调用时,运行环境会自动向该函数隐式传入this对象
- this的指向是变化的,在不同情况下函数的执行中,this的指向是不一样的!
-
- this 类似于语文上的"这"代表一个代词
-
-
-
-
- 1、当函数作为普通函数调用指向时 函数名()或IIFE 函数的this指向的是window
- 2、当函数作为某个对象的方法进行调用时,该方法的this指向的是调用者,而非持有者!
- 3、构造函数时this的指向是一个新创建的{}对象
- 正常情况下:局部作用域下声明变量或者函数,当该作用域中代码执行完毕后,该函数所声明的变量、函数就被销毁了
-
- 闭包:闭包就是当函数被嵌套声明时,并且该函数被直接或间接返回或者赋值给某个全局变量,
- 那么这个时候js内部发生一些事情
- 1、函数的地址值被返回了
- 2、产生了一个特殊的对象,闭包(在这个闭包它打包了该函数作用域上的所有的变量以及函数)
- 回调函数:将函数作为参数进行传递,传递到另一个函数中,传入的这个函数就称为回调函数!
- 回调函数的本质不是我们区调用,而是函数内部或者某个条件达成了,自动调用的!
- 正常情况下this的指向规则:
- 1、在全局作用域下访问this,this指向window
- 2、当函数以函数形式调用时,this指向window
- 3、当函数以IIFE形式调用,this指向window
- 4、当函数以方法的形式调用时,this指向调用者而非持有者
- 5、当作为构造函数调用时,this指向一个空对象{}
-
-
- 除了以上正常情况下this的指向外,还有一些非正常情况!
- this的劫持:强行的人为改变this的指向!
-
- 实现this劫持的三种方式(基于三个方式):apply call bind
-
- - apply 和call 用法基本一致
- 唯一不同之处:
- apply接受两个参数 1、对象 2、数组
- call 接受任意个参数 1、对象 其余参数就是正常的函数执行所需要的实参
- - bind
- 将函数进行改造后,并重新返回,最终执行!
-
- 箭头函数:也是函数的一种!但是相比于其他的函数形式,它很特殊!
-
- 特殊:
- 1、写法特殊
- 2、不能作为构造函数
- 3、它不具备自己的this
- 4、箭头函数不具备自己的名字
- 5、箭头函数的this无法被劫持
-
-
-
- 注意:箭头函数的this不允许被劫持!
- 构造函数:构造函数本质上是去实例一个对象,构造对象的!
- 不同的构造函数,所实例的对象是不同的!类别是不同的!
-
- 面向对象:
- java
- -封装、继承、多态
-
- 面向过程:
- c
-
- 构造函数语法规则: new 构造函数(形参列表)
-
- 构造函数与普通函数的不同:
- 1、构造函数主要目的不是去实现某个功能,主要是去实例化对象
- 2、构造函数中的this指向不同,this指向的是一个新创建的空对象{}
- 3、构造函数一般不会单独执行,应该与new配合执行
- 4、构造函数的返回值不同
- 1、如果没有return语句,默认返回新创建的那个空对象
- 2、如果有return语句,
- 情况一:如果return返回的是基本数据类型,直接无视返回值,还是返回空对象
- 情况二:如果return返回的是引用数据类型,则返回该引用数据类型!
- 注意:大部分情况下,构造函数是不写return的
- 5、构造函数的首字母应该大写!
- 注意:构造函数不要单独使用,如果单独使用构造函数将失去本身的意义
-
- new 关键字做的事情:
- 1、在构造函数中,创建一个空对象
- 2、让构造函数中的this指向这个空对象
- 3、进行对象的初始化
- 4、返回这个初始化后的对象
- 原型对象:存放在prototype属性或者__proto__属性中的对象,称作为原型对象
- prototype:存放在该属性中的对象称作为显式原型对象
- __proto__:存放在该属性中的对象称作为隐式原型对象
-
-
- 显式原型对象(prototype)的作用:
- 当函数作为构造函数使用,该属性才会发挥作用,如果是普通函数执行,原型对象毫无作用
- 当函数作为构造函数时,会创建一个实例的空对象
- 创建好空对象后,就会把prototype中指向的原型对象赋值给空对象的__proto__属性中
- 这样被创建好的空对象就具备了自己的原型对象
-
- 注意:自定义构造函数中prototype属性指向的默认是一个{}空对象
- 原生js提供的构造函数中的prototype是提前定义好的,基本不会是一个空对象
-
-
-
-
-
-
- 原型属性,每一个对象身上都具备一个属性,该属性称作为原型属性!
- 原型属性有两类:
- -显式原型属性(prototype)
- 注意:每一个函数都具备prototype并且具备__proto__
-
-
- -隐式原型属性(__proto__)
- 注意:每一个实例对象都具备__proto__
-
-
-
-
-
- 原型链:JavaScript通过每个实例对象上的__proto__隐式原型属性,将原型对象进行链接,在通过原型对象的原型属性
- 再进行链接,以此往复,直到最终的null,这样便形成了JavaScript中的原型链!
-
- 原型链的寻找一定是去__proto__寻找,而不会寻着prototype去找
- // 1、keys
- // 返回指定对象上自身的可以枚举的属性,所组成的数组
-
-
-
-
- // 2、values
- // 返回指定对象上自身的可以枚举的属性值,所组成的数组
-
-
-
-
-
- // 3、entries
- // 返回一个给定对象自身上的枚举属性的键值对
- // 1、valueOf
- // 该方法会返回指定对象(任何类型的对象)的原始值
-
-
- // 2、toString()
- // 返回一个该对象的字符串形式
-
-
- // 3、hasOwnProperty
- // 判断当前对象的某个属性是否为当前对象自身的属性,还是原型链上的
-
- // in运算
- // 判断某个属性是否存在与该对象上,包括原型链上的属性
-
-
- // 4、isPrototypeOf
- // 判断某个对象是否是另一个对象的原型对象
-
-
- // 5、propertyIsEnumerabale
- // 判断某个属性是否是可枚举属性
-
-
- // 将对象转换成字符串
- let res = JSON.stringify(obj)
- rest参数 把实参传入的多余的数据,收集起来存放的数组中
- rest参数只能放在末尾或者单独使用
-
- 例如: function fun1(a, b, ...xxx) {
- console.log(a, b, xxx);
- console.log(Array.isArray(xxx));
- }
- fun1(1, 2, 3, 4, 5, 6)
- 他会把多余的参数存在xxx这个数组对象中!
- 模板字符串 ''
-
- 例如:var str =
- `ewqe
- wqeqwe
- ewqe qw
- ewqewqr
- `
-
- 打印出来的效果:
- ewqe
- wqeqwe
- ewqe qw
- ewqewqr
3、数组中的相关遍历器
- 1、forEach方法
- 语法规则: arr.forEach(callback(elment,index,thisArg))
- element:代表当前数组中的元素
- index:代表当前数组中的元素的下标
- thisArg:接收该回调函数中的this,thisArg ===》 arr
- 回调函数,一般采用箭头函数的写法。
-
- 注意:被传入的回调函数,每访问一次数组中的元素就被执行一次!
- foreach方法的返回值是undefined
-
- 2、map方法(不改变原数组)
- 语法:arr.map(callback(elment,index,thisArg))
- 该方法会遍历每一个数组元素
- 每遍历一个元素都会调用一次回调函数,并且将该回调函数的返回值存放到新数组中,最终整体返回
-
-
-
- 3、filter方法(不改变原数组)
- 语法:arr.filter(callback(elment,index,thisArg))
- 每访问一次元素都会调用一次回调函数,如果该回调函数的返回值是一个true,那么将当前访问的元素保存到一个新数组中,最终作为filter方法的返回值
- 语法
- class student{
- // 构造器用来构造对象的
- constructor(参数列表){
-
- }
-
- // 在构造出来的对象的原型上面,
- sayhello(){
-
- }
-
- // static 关键字 静态的
- // 注意:在构造函数外,通过static修饰的属性或方法,全部加在类自身上!
- static myname(){
-
- }
- }
-
- 总结:
- 1、定义的类不具备提升操作!一定是先定义后使用
- 2、每一个类都必须且只有一个constructor方法,如果省略,js将自动补充一个空的constructor方法
- 如果类中同时存在多个constructor方法则会报错
- 3、其他与constructor方法同级方法,则作为该实例对象的原型对象上的方法! ===》Person.prototype
- 4、如果类中的方法或者变量加上static关键字,则该方法会变成类的静态方法
- 实现类的继承 extends 关键字
- 语法:A类 extends B类
-
-
- class A{
- constructor(a,b){
- this.a = a
- this.b = b
- }
-
- }
- class B extends A{
- constructor(c){
-
- super(100,200) //调用父类
- // 因为B是继承于A,所有B中的constructor方法,在使用this前必须先调用一次父类的构造函数
- this.c = c
- }
-
- }
- var、let、const三者的区别
-
- var特点:
- 1、不存在块级作用域(全局作用域、函数作用域)
- 2、可以进行变量声明的提升
- 3、可以在同一个作用域下声明同名的变量
- 4、可以改变值
- 5、不需要声明初始化(可以只声明,不赋值)
-
- let特点:
- 1、具备块级作用域(全局作用域、函数作用域)
- 2、变量会进行提升,但是存在"暂时性死区"
- 3、不可以在同一个作用域下声明同名的变量或同名的函数
- 4、可以任意的改变值
- 5、不需要声明初始化(可以只声明,不赋值)
-
- const特点:
- 1、具备块级作用域(全局作用域、函数作用域)
- 2、变量会进行提升,但是存在"暂时性死区"
- 3、不可以在同一个作用域下声明同名的变量或同名的函数
- 4、常量的值不能被改变
- 5、声明的同时必须赋值
- var obj1 = {
- name: "obj1"
- }
- var obj2 = {
- name: "obj2",
- }
-
- Function.prototype.mycall = function (objname, num1, num2) {
- objname.fn = this
- objname.fn(num1,num2)
- delete objname.fn
- }
-
- function myfun(a,b) {
- console.log(this);
- console.log(a+b);
- }
-
- myfun.mycall(obj1,1,2)
2、手写unshift方法
- // 手写unshift方法
- var arr = [1,2,3,4,5]
- Array.prototype.myUnshift = function(...value){
-
- let arr=[...this]
- let long = value.length
- console.log(long);
-
- let long1 = arr.length
- console.log(long1);
- for(let i = 0 ;i
- this[i+long] = arr[i]
- }
- this.splice(0,1,value[0])
- this.splice(1,1,value[1])
-
-
- console.log(arr);
- console.log(this);
- }
- arr.myUnshift(3,4)
- console.log(arr);
3、手写filter方法
-
- var arr = [1, 2, 3, 4]
- Array.prototype.myfilter = function (myfun) {
- var i = 0
- console.log(this);
- console.log(myfun);
-
- let arr = this
- let reuslt = []
- for(let i = 0 ; i
length;i++){ - let jieguo = myfun(arr[i],i,arr)
- if(jieguo){
- reuslt.push(arr[i])
- }
- }
-
- return reuslt
- }
-
- arr.myfilter((el, index, thisArg) => {
- console.log(el, index, thisArg);
- })
-
- arr.filter((el, index, thisArg) => {
- console.log(el,index,thisArg);
- })
4、手写sort方法
- var arr = [1, 6, 8, 7, 3, 5, 9, 4, 2, 10]
- Array.prototype.mysort = function (myfun) {
- var long = this.length
- var num
- if (myfun == undefined) {
- for (let i = 0; i < long - 1; i++) {
- for (let j = i + 1; j < long; j++) {
- if (this[i] - this[j] < 0) {
- this.splice(i, 1, this[i])
- this.splice(j, 1, this[j])
- } else {
- num = this[i]
- this.splice(i, 1, this[j])
- this.splice(j, 1, num)
- }
- }
- }
- } else {
- for (let i = 0; i < long - 1; i++) {
- for (let j = i + 1; j < long; j++) {
- if (myfun(this[i], this[j]) < 0) {
- this.splice(i, 1, this[i])
- this.splice(j, 1, this[j])
- } else {
- num = this[i]
- this.splice(i, 1, this[j])
- this.splice(j, 1, num)
- }
- }
- }
- }
-
- return this
- }
- console.log(arr.mysort());
- console.log(arr.mysort((a, b) => {
- return a - b
- }));
八、数组、字符串、对象相关的API
Array相关的API:
- # Array实例对象的API
-
- Array实例对象,length
-
- 返回或者设置数组的长度!
-
- 设置length属性后,
-
- 尽量不要设置length属性,容易造成稀疏数组
-
- 数组访问元素 数组[下标]
-
- 注意:如果访问的下标值超过数组长度,则返回undefined
-
- 数组元素的修改 数组[下标值] = 表达式
-
-
-
- 1、at方法 通过指定的数值去返回对应元素!支持负数
-
- 语法规则:at(index) index默认值为0
-
- 如果index是负值,那么则从当前元素的后面开始计算!
-
- 2、push方法
-
- 对当前元素末尾添加一个或多个新元素!该方法改变数组
-
- 返回值:数组改变后的length值!
-
- 3、pop方法
-
- 删除当前数组中的最后一个元素,并返回该方法改变数组
-
- 返回值:数组改变后的length值!
-
- 4、unshift方法
-
- 对当前数组开始位置添加一个或多个新元素!该方法改变原数组
-
- 返回值:第一个元素的值
-
- 5、shift方法
-
- 删除当前数组中的第一个数组,并返回!该方法改变原数组
-
- 返回值:数组改变后的length值!
-
- var arr = [0,1,2,3,4,5,6,7]
-
- console.log(arr.push(8),arr);
-
- console.log(arr.pop(),arr);
-
- console.log(arr.shift(),arr);
-
- console.log(arr.unshift(0),arr);
-
- 6、数组反序 reverse方法
-
- 将数组逆转
-
- console.log(arr.reverse());
-
-
-
-
-
- sort方法 排序
-
- 该方法是对数组中的元素进行排序,可接受参数,但是参数必须是函数(比较函数)
-
- 如果不传入比较函数,会按照字符编码进行排序
-
- 比较函数:函数体内部做比较运算
-
- console.log(arr.sort((a,b)=>{
-
- return b-a
-
- }));
-
- 注意:比较函数有两个参数 , a第一个比较的元素 b第二个比较的元素
-
- 大于0 升序 等于0 不变 小于0 降序
-
- concat方法
-
- 连接数组
-
- join方法
-
- 将数组中的元素进行合并,通过指定的分隔符!合并后形成一个字符串并发挥
-
- 语法规则:join(str)
-
- 默认情况 str为','
-
-
-
- splice方法
-
- 通过该方法可以删除指定元素、修改指定元素,添加指定元素 任意位置
-
- 语法规则:splice(index,hm,elmt1,elmt2)
-
- 注意:如果省略hm,则将数组清空
string相关的API:
- # String实例对象的API
-
- //charAt方法
-
- //从一个字符串中返回指定位置的字符
-
- // 语法:str.charAt([index]) []包裹的形参代表的是可选参数,不是必选,index是一个number类型
-
- //index默认值是0
-
-
-
- // charCodeAt方法
-
- // 从一个字符串中返回指定索引下对应字符的编码
-
-
-
-
-
- //检查字符串中是否包含特定的子串
-
- // 1、indexOf方法
-
- // 从当前字符串的指定位置中查找第一个出现的特定的子串的位置索引,
-
- // 如果查找成功,则返回该子串字符的首字符索引下标,如果未查找成功则返回 -1
-
- // 语法:str.indexOf("SeachValue",[fromIndex])
-
- // 注意:一般不会传入第二个参数
-
- // 注意:该方法是正向查找
-
- // 2、lastIndexOf()
-
- // 从当前字符串的指定位置中查找第一个出现的特定的子串的位置索引,
-
- // 如果查找成功,则返回该子串字符的首字符索引下标,如果未查找成功则返回 -1
-
- // 语法:str.lastIndexOf("SeachValue",[fromIndex])
-
- // 注意:一般不会传入第二个参数
-
- // 注意:该方法是反向查找
-
- // 3、incudes方法
-
- // 判断当前字符串中有没有指定的某个子串,如果有则返回true,没有则返回false
-
- // 4、starsWith方法
-
- // 判断当前字符串是否已某个指定字符串进行开头,根据情况返回true或者false
-
- // 5、endWith方法
-
- // 判断当前字符串是否已某个指定字符串进行结尾,根据情况返回true或者false
-
- //concat方法
-
- // 将一个或多个字符串与现有的字符串进行拼接,形成一个新的字符串返回
-
- //split方法
-
- //使用指定的分隔符,将一个string对象进行分割,形成一个字符串数组!
-
- //split方法的返回值是一个Array
-
- //截取字符串相关方法
-
- // 1、slice方法
-
- // 截取字符串中的一部分
-
- // slice(1,4)
-
- // 2、substring方法
-
- // 字符大小写转换
-
- // 1、toLowerCase方法
-
- // 将大写字母转换成小写字母
-
- // 2、touppercase方法()
-
- // 将小写字母转换成大写字母
-
-
-
- // 去除空白符
-
- // trim方法
-
- // 去除字符串的空白字符
-
- // 空白字符:空格 水平制表符tab 换行符 等
-
- // trimstart 去除开头空白符
-
- // trimend 去除结尾空白符
Object相关的API:
- # Object实例对象的API
-
- // 1、valueOf
-
- // 该方法会返回指定对象(任何类型的对象)的原始值
-
- // 2、toString()
-
- // 返回一个该对象的字符串形式
-
- // 3、hasOwnProperty
-
- // 判断当前对象的某个属性是否为当前对象自身的属性,还是原型链上的
-
- // in运算
-
- // 判断某个属性是否存在与该对象上,包括原型链上的属性
-
-
-
- // 4、isPrototypeOf
-
- // 判断某个对象是否是另一个对象的原型对象
-
-
-
- // 5、propertyIsEnumerabale
-
- // 判断某个属性是否是可枚举属性
-
- // 将对象转换成字符串
-
- let res = JSON.stringify(obj)
九、总结
经过两周JS的学习,感觉JS总体来说还是比较简单的,难点主要在于函数的闭包还有作用域链、原型链。还有就是在学习对象的时候,特别要主要不要把变量和对象中的属性混为一谈,这是两个不同的东西。