js的基本语法
1.js注释
单行注释//
多行注释/**/
2.分号
每一行以分号结尾,不强制要求
3.严格区分大小写
4.js中有空格和折行会被忽略
5.代码块{...}
js的使用位置
1.head重script标签里
2.引入外部的js <script src="./js/javaScript.js"></script>
3.标签中使用
变量
// 就是一个用于存放数值(也叫字面量)的容器
// 变量的独特之处:它存放的数值是可以改变的,它没有自己的类型
// 变量声明
// 使用let var关键字来声明变量
// 区别:let有作用域
// 如果只声明不赋值,undefined
// 变量赋值
// 使用'='来给变量赋值
// 一般情况下声明和赋值同时进行
//内存结构(理解) 赋的值其实是在内存中调用值的地址
//常量
// 使用const声明,只能赋值一次 声明后立即赋值
//标识符
// 可以自主命名的内容
// 像变量名、函数名、类名
// 有命名规范:
// 1.只能含有字母、数字、下划线、$、并且不能以数字开头
// 2.不能是js的关键字和保留字
// 3.不建议使用内置函数或类名
// 4.建议使用驼峰命名法 首写字母小写,每个单词开头大写
// 例:minWidth borderTopWidth
// 常量命名 :字母全部大写 PI MINWIDTH
基本数据类型
// 1.数值 Number
// 包含整数、小数
// js的数值不是无限大
// Infinity 一个特殊的数值 无限大
// NaN 是一个特殊值 表示非法数值
// 2.大整数 BigInt
// 表示一些较大的整数 不能表示小数
// a= 99999999999999999999999999 n;
// (大整数和整数不能直接运算)
// 其他进制
// 3.字符串 String
// 使用''或""来表示字符串,成对使用(解决方式:1.混合使用"''"或'""' 2.使用转义字符\ )
// 模板字符串``
// 4.布尔值 Boolean
// 也被称为逻辑值或真假值类型
// true false 是布尔值的两种数值
// 本质就是0和1
// 5.空值 Null
// 表示一个空对象
// 6.未定义 undefind
// undefind 实际是由null值衍生出来的
// 区分: null 用户不主动用 js自己用
// undefind 给程序员用
// 7.符号 Symbol
// 用来创建唯一的标识
// 七种原始值:构成程序世界的基础。在js中是不可变类型,一旦创建不可修改
// typeof检查数据类型
类型转换
// 指的是将一个数据类型强制转换为其它的数据类型
// 一般指的是将其他的数据类型装换为String、number、boolean.
// 1.转换为字符串:
// 1.1 调用toString()方法
// a的b方法 a.b()也就是 a.toString()
// 1.2 String() 函数
// b=String(b)
// 原理:对于有tostring()方法的值调用string函数的时候,实际使用的还是tostring()方法
// 对于不能使用tostring()方法的值,则直接转换
// 例如: null和undefined没有tostring()函数,但可以用string()函数进行转换
// 2.转换为数值:
// 2.1 Number() 函数
// 合法字符串 可以转换为数值
// 不合法字符串 转换为NaN
// 空字符串和空格 转换为0
// 布尔值转换 true为1 false为0
// null转换为0 undefined转换为NaN
// 2.2专门把字符串转数值
// parseInt()把字符串转换成一个整数 前提是字符串要以数字打头否则还是NaN
// parseFloat() 把字符串转换为一个浮点数,保留小数位
// 3.转换为布尔值:
// 3.1 Bollean()函数
// 数值转布尔 0和NaN转换为false其余都是true
// 字符串转布尔 空串为flase其余都为true
// null 和 undefined都转换为flase
运算符
// 1.算术运算符
// + 加法运算符
// - 减法运算符
// * 乘法运算符
// / 除法运算符
// % 模运算符 取余
// ** 幂运算
// 当任意一个值和字符串做加法运算时,先把其他值转换为字符串,然后进行拼接
// 两元运算符:+-*/ 一元运算符:正负号
// 2.赋值运算符
// =
// += -= *= /= %= **=
// 3.自增运算符 ++ 自减运算符--, ++会使原变量增加1 --会使原变量减去1
// 前自增 ++a 后自增 a++
// 返回值 ++a 自增后的值 新值;a++ 自增前的值 旧值
// --同理
// 4.逻辑运算符
// 逻辑非 !
// 逻辑与 && (两边都是真才是真)
// 非布尔值时要先转为布尔值再返回原值
// 先转换第一个值,为false,返回第一个值,为true,返回第二个值
// 逻辑或 || (有一个真就是真)
// 非布尔值时要先转为布尔值再返回原值
// 第一个值为true时,返回第一个值
// 第一个值为false时,返回第二个值
// 5.关系运算符
// > < >= <=
// 非数值进行关系运算,先转换为数值再比较
// 字符串比较,比较的是unicode编码
// 6.相等运算符
// == 比较两个值是否相等
// 不同类型的值比较时,先转换为同类型(一般是数值)再比较
// null == undfined
// NaN跟任何值都不相等,包括他自己
// === 全等
// 不会自动类型转换,类型不同直接false
// != 不等
// 会自动类型转换
// !== 不全等 严格不相等
// 不会自动类型转换
// 7.条件运算符
// 语法:条件表达式?表达式1:表达式2
// 条件表达式为真返回表达式1 为假返回表达式2
代码块
//
// {
// let a = 100;
// alert('你好');
// console.log(a);
// }
流程控制
// 1.if语句
// 语法:if(条件表达式){语句....}
// 2.if-else语句
// 语法:if(条件表达式){语句1....}else{语句2...}
// 满足执行1 不满足执行2
// 3.if - else if - else语句
// 语法:if(条件表达式1){语句1}else if(条件表达式2){语句二}....else{语句n}
// 注意:这个语句只有一个代码块会被执行,一旦有了执行的代码块,下面的条件都不会继续判断,一定要注意条件的编写顺序
// 4.switch语句
// 语法:switch(表达式){case 表达式1:语句1 case 表达式2:语句2}
// 执行流程:switch表达式=== case表达式1 true就从case执行语句1
// false就继续比较case2,直到true为止
// break;跳出循环 default:默认
// if和switch 功能重复,不同在于,switch 在多个全等判断时,结构比较清晰
// isNaN来检查一个值是否是NaN,返回true或false
循环语句
// 通过循环语句可使指定的代码反复执行
// 1.while语句
// 语法:while(条件表达式){语句//循环体}
// 执行流程:while执行时,循环先对条件表达式进行判断,如果true,则执行循环,执行完毕继续判断条件表达式,知道False出现为止
// 注:当一个循环的表达式恒为true,则是死循环
// 循环的三个条件
// 1.初始化表达式
// 2.条件表达式
// 3.更新表达式
// 2.do-while语句
// 语法:do{语句}while(条件表达式)
// 执行流程:先执行do后的循环体,执行完毕后,再对while的条件表达式进行判断,如果是true继续循环,false则结束
// while和do-while区别:while先判断在执行 do-while先执行在判断(实质区别:do-while可以确保至少执行一次)
// 3.for语句
// 语法:for(初始表达式;条件表达式;更新表达式){语句}
// 执行流程:1.执行初始化表达式
// 2.执行条件表达式,判断循环是否执行,true执行false终止
// 3.条件表达式为true则执行循环体
// 4.执行更新表达式,对初始化变量进行修改
// 5.重复执行第2步,知道条件表达式为false
//
break和continue
// break用来终止循环,只能终止最近的循环
// continue用来跳过当次循环
//
对象
// 是js中的一种复合数据类型
// 创建对象
// 方式1:let obj=Object();
// obj.name = '小李飞刀'
// obj.age = 30
// obj.gender = '男'
// 方式2:let obj={}
// let obj1 = {
// name: '天机老人',
// age: 100,
// hobby: {
// a: '说书',
// b: '旅游'
// }
//}
// 添加属性
// 语法:对象.属性名=属性值
// 读取属性
// 语法:对象.属性名
// 如果读取的是一个对象中没有的属性,报undefined
// 属性名 通常是一个字符串,没有特殊要求
// 如果很特殊,就用[]来设置,建议属性名要符合标识符的规范
// []也可以传变量,但是属性名是变量的值
// 属性值
// 可以是任意数据类型,也可以是一个对象
// 检查对象中是否有某个属性:in运算符
// 语法:属性名 in 对象
// 获取对象中的所有属性
// 语法:for(let 属性名变量 in 对象){
// 语句
// }
// 执行流程:for-in会根据属性的个数 执行多次
// 每次执行,八属性名赋值给所定义的变量prorName
// 如果两个变量同时指向一个对象,==比较的是两个变量指向的内存地址,如果通过一个变量修改了对象,另一个变量也受影响
// 修改变量 和 修改对象
// 修改对象时,如果有其他变量指向此对象,所有只想的变量都会受到影响
// 修改变量时,只影响当前的变量
// 开发中声明对象通常用const来声明,赋值只有一次,但对象可以修改
函数 function也是一个对象
// 函数可以存储代码,在需要的时候可以调用
// 创建函数:
// 1.函数声明 function 函数名(){函数体}
// 2.函数表达式
// const 变量 = function(){
//
// } (匿名函数)
// 3.箭头函数
// const 变量 = ()=>{函数体} 如果只有一行语句,可以省略{}
// 调用函数:执行像函数中的代码 函数名()
// 检查函数的类型:typeof 函数名 function类型
//
// 函数参数
// 形式参数
// 定义函数时,可以指定数量不等的参数
// 实际参数
// 在调用函数时,在函数()中传入的参数
// 例: function sum(a, b) {
//
// console.log(a + b)
// }
// sum(2, 3)
// 1.实参数量=形参数量 实参赋值给对应的形参
// 2.实参数量>形参数量 多余的实参不生效
// 3.实参数量<形参数量 多余的形参自动赋值undefined
// 函数返回值
// return
// 函数调用之后,函数的执行结果就作为结果返回
// 任何值都可以作为返回值使用(包括函数)
// 如果return后不跟任何值,相当于返回undefined,不写return也返回undefined
// 执行return后,函数就结束了,后面的代码不再执行
函数参数(补)
// 对象可以作为函数的参数
// 函数每次调用,都会重新创建默认值
// 函数也可以作为函数的参数
// 匿名函数也可以作参数
// 箭头函数也可以作参数
// 函数方法(methods)
// 当一个对象的属性是一个函数,那么就称这个函数是该对象的方法
// 调用函数也叫访问对象的方法
// 语法:对象.方法()
// 箭头函数的参数
// 当箭头函数只有一个参数,()可以省略
// 当箭头函数只有一行代码,{}可以省略
// 当给参数指定默认值
// 如果有实参,就赋值
// 如果没有,就使用默认值
// 箭头函数返回值
// return关键字
// 函数体只有一行语句,可以省略{},return
// 如果返回值是对象,需要加上() 例:const fn()=>({name='小李飞刀'})
作用域
// 一个变量的可见区域叫作用域
// 全局作用域:生命周期:在网页生成时创建,关闭时销毁
// 所有直接写在script标签中的代码都是全局作用域,可以在任意位置访问
// 局部作用域
// 块作用域,生命周期:在代码块执行时创建,在代码块结束时销毁
// 在块作用域中声明的变量是局部变量,只能在块内部访问,外部无法访问
//
// 函数作用域
// 生命周期:在函数调用时产生,结束时销毁
// 函数每次调用,都会产生一个全新的函数作用域,只能在块内部访问,外部无法访问
// 作用域链
// 当使用一个变量时,js引擎就会在当前的作用域中寻找,
// 如果找到直接使用
// 如果没有,就去上一个作用域找,找到了就使用
// 找到全局作用域也没找到,则报错
// window对象
// 通过window对象,可以对浏览器窗口进行各种操作
// window对象负责存储js中的内置对象及浏览器的宿主对象
// window对象的属性可以通过window对象访问,也可以直接访问
// 使用function声明的函数都可以认为是window对象的方法保存
// var 和 let
// var声明的变量,作为window对象的属性来保存,是一个全局变量
// let声明的变量,不会存在window对象中,存在秘密的地方
// let增加了变量的安全性 window对象中的变量是不安全的
// 在局部作用域中,如果没有let和var声明,则变量自动成为window对象的属性,也就是全局变量,这样不推荐,一定要先声明
// this
// 函数执行时,js引擎会传递一个隐含的参数this
// this会指向一个对象
// this所指向的对象会根据函数调用方式的不同而不同
// 1.以函数形式调用时,this指向window对象
// 2.以方法形式调用,this指向的是调用方法的对象
// *谁调用,this就指向谁
// 箭头函数的this
// 箭头函数没有自己的this,它的this是由外层的作用域决定的
// 对象不产生作用域
立即执行函数(IIFE)
// 1.是一个匿名函数,并且只调用一次
// 2.可以利用立即执行函数,创建一个一次性的作用域,避免变量冲突
// 例: (function(){代码内容}()); 要加分号,避免解析出错
// js运行代码的模式
// 1.正常模式
// 默认情况下代码运行在正常模式中
// 语法检验不严格,它的原则:能不报错尽量不报错
// 2.严格模式
// 语法检验变得严格
// 1)禁止一些语法
// 2)更容易报错
// "use strict"可以作为全局的严格模式,也可以放在函数中作为该函数的严格模式
// 在开发之中尽量 使用严格模式
面向对象
1.程序是干嘛的?
// 程序是对现实世界的抽象
2.对象是干嘛的?
// 一个事物抽象到程序中
// 在程序中,一切皆是对象
3.面向对象编程
// 所有的操作都是通过对象来完成
// 做任何事情之前先找到对象,通过对象来完成各种操作
// 通过object创建对象时,不能区分不同类型的对象,不方便批量创建对象
// js中通过类class来解决问题
// 1.类是对象的模板
// 语法: class 类名{} 类名要使用大驼峰命名
// 例: class Person{}
// const p1=new Person()创建对象
// 2.同类对象 通过同一个类创建的对象
// 可以使用instanceof来检查一个对象是否由某个类创建
// p1 instanceof Person
// 创建类
// 类的代码块中,是用来设置对象的属性
// 实例属性,创建的对象所具有的属性
// 静态属性/类属性 static
// 类中的方法
// 构造方法/构造函数/构造器 constructor(){} new的时候执行
// 给创建的对象属性赋值
// 构造函数中this指向当前所创建的实例即对象
面向对象的三大特点
// 封装、继承、多态
// 1.封装
// 对象是用来存储不同属性的容器(装)
// 对象保证数据的安全(封)
// 怎么保证数据安全:
// 1、私有化数据 加#
// 2、开放setter getter方法操作私有属性
// 可以控制属性的读写权限
// 可以在方法中对属性值进行验证
// 3.js提供了简单的方式
// 语法:get 属性名(){return this.#属性}
// set 属性名(参数){this.#属性=参数}
// 2.多态
// 如果一个东西走路像鸭子,叫声像鸭子,那他就是一只鸭子
// 多态提供了灵活性
// js中不检查参数的类型,即任何数据都可以作为参数来传递
// 要使用某函数,不需指定值类型,只需参数对象满足某些条件即可
// 3.继承
// 继承开始extends
// 子类可以创建同名方法重写父类的方法
// 通过继承,可以在不修改一个类的情况下对其进行一些扩展
// 遵循ocp原则,即开闭原则
// 如果需要增添属性,需要重写构造函数 super()是调用父类的构造函数,必须写
对象中存储属性的区域
// 1.对象自身
// 直接通过对象所添加的属性
// 在类中通过x=y的形式添加的属性
// 2.原型对象(prototype)
// 对象中还有一些内容,会存到原型对象
// 在对象中会有一个属性来存储原型对象,__proto__
// 原型对象也是负责为对象存储属性
// 当我们访问对象中的属性,会优先访问对象自身的属性,对象自身不包含该属性,会去原型对象中找
// 会添加到原型对象中的属性:
// 在类中通过XXX(){}添加的方法,位于原型中
//
// 原型对象
// 访问一个对象的原型对象
// 对象.__proto__
// Object.getPrototype(对象)
// 原型对象中的数据
// 1.对象的数据(属性,方法等)
// 2.构造函数constructor
// 注意:原型对象也有原型 这样就构成了一条原型链,根据对象的复杂程度不一样,原型链的长度也不一样
// p1对象的原型链:
// p1-->原型--->原型-->null
// 原型链
// 读取对象属性时,优先找对象自身属性
// 如果对象中有,则使用,如果没有则去对象的原型中找
// 如果原型中有,则使用,如果没有则去原型的原型中找,直到找到object对象的原型(null)
// 如果依然没有找到,返回undefined
// 不同
// 作用域链:是找变量,找不到报错
// 原型链:找属性,找不到返回undefined
// 原型的作用
// 相当于一个公共的区域,可以被该类所有的实例访问
// 这样把该类所有的实例的所有公共的属性(方法)统一存到原型中
// 我们只需要创建一个方法,就可以被所有实例使用
// js中的继承是通过原型来实现的
// 当继承时,子类的原型就是一个父类的实例
// 修改原型(大部分情况下,不需要修改原型对象)
// 原则:尽量不要手动修改
// 要改,不要通过实例对象去改,要通过类.prototype属性去改
// instanceof 用来检查一个对象是否是一个类的实例
// 只要原型链上有该类实例,就返回true
// new运算符
// 1. 创建一个空的简单 JavaScript 对象(即 {});
// 2. 为步骤 1 新创建的对象添加属性 __proto__,将该属性链接至构造函数的原型对象;
// 3. 将步骤 1 新创建的对象作为 this 的上下文;
// 4. 如果该函数没有返回对象,则返回 this。
// 面向对象总结:
// 面向对象的本质:所有操作都是通过对象来进行的
// 面向对象的编程步骤:1.找对象 2.操作对象
// 学习对象:1.明确对象代表什么 有什么用
// 2.如何获取这个对象
// 3.如何操作使用这个对象
// 对象分类:
// 内建对象 ES标准所定义的对象 Object String Number
// 宿主对象 浏览器提供的对象 Bom Dom
// 自定义对象 开发人员自己创建的对象