js初级阶段学习笔记,供参考
认识javascript
什么是计算机语言
电脑是由人操控的一台机器,但是操控需要媒介,计算机语言就是人来操控计算机的媒介。(javascript语言、c语言、java语言、php语言等等都是高级计算语言,在我这里主要认识javascript语言简称js)
javascript简史
- javascript是由网井公司发明(起初叫Livescript),后来SUN公司介入从而正式改名为javascript;
- 1996年微软在ie3浏览器上注入了自己对javascript的实现JScript
- 为了确保不同浏览器上运行的javascript标准是一致的,所以几个公司共同定制了js的运行标准并且命名为ECMAScript。
javascript的起源
javascript起源于1995年,他的出现主要用于处理网页中前端的验证。所谓前端验证,就是指检查用户的输入是否符合规范与规则,比如用户名的长度,密码的长度,邮编的格式!
我们把javascript又称之为js。
javascrip的构成
一个完整的javascript实现应该有三个部分构成分别是ECMAScript、DOM、BOM。ECMAScript是javascript的一个标准定义了javascript的关键字与运行标准,一般来讲他们指的是同一个东西。但是实际上javascript的含义更大一些,包含了他们三个。
javascript特点
-
解释型脚本语言
JavaScript 是一种解释型脚本语言,与 C、C++ 等语言需要先编译再运行不同,使用 JavaScript 编写的代码不需要编译,可以直接运行。 -
基于对象
JavaScript是一种基于对象的脚本语言,使用 JavaScript 不仅可以创建对象,也能操作使用已有的对象。 -
弱类型
JavaScript 是一种弱类型的编程语言,对使用的数据类型没有严格的要求,例如您可以将一个变量初始化为任意类型,也可以随时改变这个变量的类型。 -
动态型
JavaScript在运行过程中才会检测数据类型,不会指定数据类型,自身函数结构也可以在运行中根据需要发生变化。 -
跨平台
JavaScript 不依赖操作系统,在浏览器中就可以运行。因此一个 JavaScript 脚本在编写完成后可以在任意系统上运行,只需要系统上的浏览器支持 JavaScript 即可。
javascript可以做什么事情
可以对已有的html网页做一些交效果,更改样式,内容,数据,通俗来说就是对网页进行操控,让网页变得灵活,注入网页的灵魂。
javascript声明变量
js注释
/* 多行注释 */
// 单行注释
js输出方式
console.log('在控制台输出')
console.dir('在控制台输出对象信息')
alert('在页面弹出一个提示框')
prompt('在页面弹出一个输入框')
变量
白话:变量就是装东西的盒子
定义:变量就是用于存放数据的容器,我们通过变量名获取数据,它也可以修改
本质:变量就是程序向内存中申请一块用来存放数据的空间
变量的使用
变量在使用分为两步 声明>赋值
var 关键字声明变量
var age;
在这里age是程序员定义的变量名,我们通过变量名访问内存中分配的空间。
语法:var 变量名 = 值
= 等号用作赋值操作,将等号右边的值赋给左边的变量名空间中
```js
var a = 1
// 将1存入变量名为a的空间中= 用做赋值
var 关键字有预解析功能(在js在加载时js会将var关键字声明的空间提前声明出来,在执行到具体位置后在进行赋值)
console.log(a) //undefined 就是声明了未定义
var a = 2
console.log(a) //2 在赋值之后打印结果
关键字与保留字
关键字:是指 JS本身已经使用了的字,不能再用它们充当变量名、方法名。
包括:break、case、catch、continue、default、delete、do、else、finally、for、function、if、in、instanceof、new、return、switch、this、throw、try、typeof、var、void、while、with 等。
保留字:实际上就是预留的“关键字”,意思是现在虽然还不是关键字,但是未来可能会成为关键字,同样不能使用它们当变量名或方法名。
包括:boolean、byte、char、class、const、debugger、double、enum、export、extends、fimal、float、goto、implements、import、int、interface、long、mative、package、private、protected、public、short、static、super、synchronized、throws、transient、volatile 等。
数据类型
为什么需要数据类型
- 在计算机中,不同的数据所需占用的存储空间是不同的,为了便于把数据分成所需内存大小不同的数据,充分利 用存储空间,于是定义了不同的数据类型。 简单来说,数据类型就是数据的类别型号。比如姓名“张三”,年龄18,这些数据的类型是不一样的。
- 变量是用来存储值的所在处,它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的 内存中。JavaScript 是一种弱类型或者说动态语言。这意味着不用提前声明变量的类型,在程序运行过程中,类型会 被自动确定。
var age = 10; // 这是一个数字型
var sty = '你好,javascript;'; // 这是一个字符串
- 在代码运行时,变量的数据类型是由 JS引擎 根据 = 右边变量值的数据类型来判断的,运行完毕之后, 变量就确定 了数据类型。
- JavaScript 拥有动态类型,同时也意味着相同的变量可用作不同的类型:
数据类型
JS 把数据类型分为两类:
- 简单数据类型 (Number String Boolean Undefined Null)
- number 数字型,包含了整型和浮点型(10,15.2,0.2)
- string 字符串型,‘张三’,“李四” (字符串都带有双引号或者单引号)
- boolean 布尔值 false ,true 等价于0和1
- undefined 声明了未定义,声明变量a 但是a并未赋值此时a为undefined
- null 空值 var a = null 声明了变量a为空
- 复杂数据类型 (object)
number 数字类型
- 最大值:Number.MAX_VALUE,这个值为: 1.7976931348623157e+308
- 最小值:Number.MIN_VALUE,这个值为:5e-324
- Infinity ,代表无穷大,大于任何数值
- -Infinity ,代表无穷小,小于任何数值
- NaN ,Not a number,是计算机科学中数值数据类型的一类值,表示未定义或不可表示的值。常在浮点数运算中出现
string字符串类型
- 可以是引号中的任意文本,其语法为 双引号 “” 和 单引号’‘
- 因为 HTML 标签里面的属性使用的是双引号,JS 这里我们更推荐使用单引号。
- 字符串拥有length属性,字符串长度
var strMsg = "你好,javascript;";
// 使用双引号表示字符串
var strMsg2 = '你好,javascript';
// 使用单引号表示字符串 常见错误
var strMsg3 = 你好,javascript;
// 报错,没使用引号,会被认为是js代码,但js没有这些语法
/*
转义字符
类似HTML里面的特殊字符,字符串中也有特殊字符,
我们称之为转义符。
转义符都是 \ 开头的,常用的转义符及其说明如下:
*/
'\n 换行'
'\t 缩进'
'\b 空格'
//字符串拥有length属性,字符串长度
var str = '你好JavaScript'
console.log(str.length)//长度为12
- 字符串拼接
- 多个字符串之间可以使用 + 进行拼接,其拼接方式为 字符串 + 任何类型 = 拼接之后的新字符串
- 拼接前会把与字符串相加的任何类型转成字符串,再拼接成一个新的字符串
//字符串 "相加"
alert('hello' + ' ' + 'world'); // hello world
//数值字符串 "相加"
alert('100' + '100'); // 100100
//数值字符串 + 数值
alert('11' + 12); // 1112
布尔型 Boolean
- 布尔类型有两个值:true 和 false ,其中 true 表示真(对),而 false 表示假(错)。
- 布尔型和数字型相加的时候, true 的值为 1 ,false 的值为 0。
console.log(true + 1); // 2
console.log(false + 1); // 1
Undefined
- 声明后没有被赋值的变量会有一个默认值 undefined ( 如果进行相连或者相加时,注意结果)
var variable;
console.log(variable); // undefined
console.log('你好' + variable); // 你好undefined
console.log(11 + variable); //
NaN console.log(true + variable); // NaN
null
一个声明变量给 null 值,里面存的值为空
var vari = null;
console.log('你好' + vari); // 你好null
console.log(11 + vari); // 11
console.log(true + vari); // 1
检测数据类型
- 使用typeof 检测数据类型
- typeof 运算符把类型信息当作字符串返回。
- typeof 返回值有六种可能: “number,” “string,” “boolean,” “object,” “function,” 和 “undefined”
var a = 1;
console.log(typeof a) ; // number
var str = '你好javascript~';
console.log(typeof str) ;// string
字面量
顾名思义,就是字面意思
字面量是在源代码中一个固定值的表示法,通俗来说,就是字面量表示如何表达这个值。
var a = 1;//这里的1就是字面量
数字字面量:8, 9, 10
字符串字面量:‘程序员’, “大前端”
布尔字面量:true,false
数据类型转换
强制数据类型转换
数据类型转换分为强制类型转换和隐式类型转换,就是将一种类型转换为另外的一种类型
-
强制类型转换
-
转数字
Number()直接转换成数组
parseInt()转换成整型
parseFloat()转换成浮点数 -
转字符串
srting()将其他类型字符串转换成
toString将其他类型字符串转换成(不可以转换undefined和null) -
转布尔值
Boolean()将其他类型转换成布尔值 特殊值( 0 ,字符串的空值,undefined , NaN,null等转换成布尔值全部为false,其他值为true)
-
-
数字类型转换
var a = '11';//声明字符串类型的11
var b = Number(a); //的到数字类型的11
var a = '11.11';//声明字符串类型的11
var b = parseInt(a); //得到整型数字的11
var a = '11.11';
console.log(parseFloat(a));//得到浮点型数字的11.11
- 字符串转换
var a = 11;
String(a);//得到字符串的'11'
var b = undefined ;
String(b);//得到字符串的'undefined '
var c = 11;
c.toString();//得到字符串的'11'
var d = undefined;
d.toString();
//报错Uncaught TypeError: Cannot read properties of undefined (reading 'toString')
- 布尔型转换
var a = 0;
var b = undefined;
var c = '';
var d = NaN;
var e = null;
Boolean(a);//得到false
Boolean(b);//得到false
Boolean(c);//得到false
Boolean(d);//得到false
Boolean(e);//得到false
var f = 1;
var i = '1'
Boolean(f)//得到true
Boolean(i)//得到true
隐式类型转换
- 隐式类型转换就是js自身在运算时将数据统一成一致的数据类型在进行计算因为不同的数据类型cpu无法做出计算
- 运算符
- 一元运算符 (存在隐式类型准换)
- 正号 + 对结果不会产生影响
- 负号 - 会将正值转换为负值 负值转化为正值
- 二元运算符(存在隐式类型准换)
+加 (特殊如果有值为字符串会优先做字符串拼接 /转字符串/,在进行数学加法运算(转数字))
-减 *乘 /除 %取余(做数字类型准换) - 比较运算符 (转化为数字类型 === 与=除外)结果为布尔型数据
(>大于) (>=大于等于) ( <小于 )(<=小于等于 )( 相等)(!= 不相等)(===全等) (!==不全等) - 关系运算符(转化为布尔型)结果也为布尔型数据
&&逻辑与 || 逻辑或 !逻辑非(又称之为取反)
- 一元运算符 (存在隐式类型准换)
console.log(1 + '2');//得到字符串的'12'
console.log(1 + undefined);//得到数字类型的NaN
console.log(5 * '1');//得到数字类型的5
console.log(1 < '5');//得到布尔值true
console.log(1 && 0)//得到布尔值false
语句结构
分支语句
- 顺序语句:从上往下依次执行,每个语句后面都加一个;分号。
- 分支语句:
- 程序执行遇到了要分开执行的地方了。
- 执行时遇到一个条件,如果满足,就继续执行。如果不满足,就执行其他的。
- 智能就是通过分支来执行的。
// 范围性判断
if(条件表达式){
//条件表达式为true执行 false不执行
}
if(条件表达式){
//条件表达式为true执行 false不执行
}else{
//条件表达式false时执行else中代码
}
if(条件表达式1){
//条件表达式1为true执行 false不执行
}else if(条件表达式2){
//条件表达式2为true执行 false不执行
}else{
//条件表达式1和2false时执行else中代码
}
//可以得到精确的值的判断
switch(表达式){
case 1://表达式结果为1时执行
console.log(111)
break;
case 2://表达式结果为2时执行
console.log(222)
break;
default://表达式结果不符合上边的值是时执行
console.log(333);
}
循环语句结构
- 可以重复执行一段代码
for(计数器; 条件表达式; 操作表达式){
循环体
}
计数器
while(条件表达式){
循环体
操作表达式
}
//计数器
do{
循环体
操作表达式
}while(条件表达式)
<!-- 至少循环一次 -->
条件表达式结果为true的时候会造成死循环
递增
前置递增 ++i 先自增在赋值
后置递增 i++ 先赋值在自增
console.log(++i)
console.log(i++)
i++
++i
递减同理
i–
–i
数组
数组定义: 一组数据的有序的集合
数组声明方式有几种 2种
1. new Array() 构造器的方式创建数组
2. [] 字面量创建数组
数组他的数据类型是什么 object(复杂类型数据存放在堆中)数组又称之为引用类型
检测数组的方法,不是用typeof使用typeof 得到数据类型为object
Array.isArray(arr) //返回布尔值,是数组返回true否则false
3. 数组遍历
var arr = [1,2,3,4,5,6]
for(var i = 0 ; i < arr.length ; i++){
console.log(i)
}
数组方法
Array.isArray(arr) //返回布尔值,是数组返回true否则false
var arr = [1,2,3]
arr.join('') //转字符串
arr.push()//向最后添加元素
arr.pop()//删除最后一位
arr.unshift()//向第一位添加元素
arr.shift()//删除第一位
arr.slice(起始位置,结束位置)//截取从起始位置到结束位置的
arr.slice(起始位置)//截取从起始位置到最后
arr.slice(负值)//截取 从长度的后边开始向前数x为
arr.indexOf()//检测包含某个值否 有值返回该值的下标,否则返回-1
arr.lastIndexOf()//从后向前查找第一个匹配元素有的话返回该值的下标,否则返回-1
arr.splice(下标,删除个数,替换的值)// 可以增删改
arr.forEach(function(元素,下标,数组本身){ //循环数组的 callback函数
console.log(元素)
})
对象
1. 几种声明方式
三种
1. var obj = new Object()
2. 自己设置的构造函数
function Man(name,age,sex){
this.name = name
this.age = age
this.sex = sex
}
var man = new Man('man','18','男')
3. 通过字面联量的方式 对象字面量{}
var obj = {
name:'obj',
type:'object'
}
2. 对象的查找
1 通过点的方式查找name属性
obj.name
2 通过中括号的方式查找name属性
obj['name']
3. 对象的添加
1 通过点的方式增加name属性
obj.name
2 通过中括号的方式增加name属性
obj['name']
4. 对象的修改
1 通过点的方式增加name属性
obj.name = '属性值'
2 通过中括号的方式增加name属性
obj['name'] = '属性值'
5. 对象的属性的删除
delete obj.name
delete obj['name']
6. 对象的遍历 for in 语句
for( var k in obj ){ //k当作计数器 k是字符串格式的属性名
console.log(obj[k])
}
函数 function
1. 命名函数
1.
function 方法名(){
函数体
}
调用
2.
方法名()
var 方法名 = function(){
函数体
}
调用
方法名()
2. 匿名函数
自执行函数
1.
(function(){
console.log(111);
})();
2.
(function () {
alert('匿名函数执行方式二')
}());
参数
1. 形参
在函数定义的时候的参数
2. 实参
在调用的时候使用的参数
3. 实参和形参的关系
形参负责接收在函数调用时传进来的实参
4. 个数的匹配问题
1. 实参大于形参
按照顺序接收多余的不接收
2. 实参小于形参
按照顺序接收多余的为undefined
5. arguments对象
负责接收所有传进的实参 (是一个伪数组)伪数组 有数组的属性,但是没有数组的方法
function index(){
console.log(arguments)
}
index(1,2,3,4,5,6,7,8,9)
6. 作用域
1. 全局作用域
整个js文件
2. 局部作用域
函数体内部
3. 全局变量
可以在整个js文件中使用
4. 局部变量
只能在函数体内部使用
7. 作用域链
如果函数去使用一个变量,函数先会在自己的作用域中查找,
如果找到直接使用,没找到向上层作用域中查找,如果还是没有就继续向上层查找,直到全局作用域中,如果没找到报错
这样的链式关系叫作用域链
8. return 关键字
指定函数返回值
指向return后函数不在继续向下执行
普通函数中的this指向window对象
构造函数
对象的制造工厂
function Man(name,age,sex){
this.name = name
this.age = age
this.sex = sex
this.fn = function(){
console.log('我要挖野菜!!!')
}
}
var man = new Man(1,2,3) //对象的实例化
console.log(man)//实例化对象
man.fn()//调用man对象下的fn方法
// 使用new关键字调用函数
// new 关键字做的四件事
// 1. 声明一个空对象
// 2. 将函数中的this指向空对象
// 3. 执行函数中的代码给这个空对象绑定属性
// 4. 在函数执行完将对象作为函数的返回值返回出来
构造函数的圆型对象prototype
function Man(name,age,sex){
this.name = name
this.age = age
this.sex = sex
this.fn = function(){
console.log('我要挖野菜!!!')
}
}
var man = new Man(1,2,3) //对象的实例化
console.log(man)//实例化对象
man.fn()//调用man对象下的fn方法
var 公主 = new Man('公主',18,'女') //对象的实例化
console.log(man)//实例化对象
公主.fn()
var 宝钏 = new Man('宝钏',34,'女') //对象的实例化
console.log(man)//实例化对象
宝钏.fn()
console.log(man.fn === 宝钏.fn) //false
console.log(公主.fn === 宝钏.fn) //false
//这里的实例化对象都使用的是fn方法且功能一样但使用的不是同一个函数
//且函数是个复杂类型的数据,存储会占用空间
- 问题:
- 在每个实例化对象下都存在了fn方法,这个方法时构函数给每个实例对象都单独绑定的,但是做的事情是相同的,这样就有点浪费资源
- 解决方案:
- 构造函数拥有一个原型对象(prototype),这个对象中的属性和方法可以被构造函数的实例对象共享,可以将同样的方法和属性绑定给构造函数的原型对象
- 这样就可以共方法和属性了
- 原理:每个对象都有一个隐式原型(oroto),他指向了构造函数的原型对象,同过他可以实现属性和方法的共享
- 原型对象中有一个constructor属性指向了他的构造函数
function Man(name,age,sex){
this.name = name
this.age = age
this.sex = sex
this.fn = function(){
console.log('我要挖野菜!!!')
}
}
Man.prototype.fn = function(){
console.log('我要挖野菜!!!')
}
var man = new Man(1,2,3) //对象的实例化
console.log(man)//实例化对象
man.fn()
var 公主 = new Man('公主',18,'女') //对象的实例化
console.log(man)//实例化对象
公主.fn()
var 宝钏 = new Man('宝钏',34,'女') //对象的实例化
console.log(man)//实例化对象
宝钏.fn()
console.log(man.fn === 宝钏.fn)//true
console.log(公主.fn === 宝钏.fn)//true
//在这种情况下使用的方法是同一个函数使用的都是原型对象下的方法
console.log(man.__proto__===Man.prototype)//true
//在原型对中的constructor指向自己的构造函数
//在构造函数中对象实例的__proto__(隐式原型属性)与构造函数的prototype属性指向的是同一个地方
console.log(man.__proto__.constructor)//Man构造函数
console.log(Man.prototype.constructor)//Man构造函数
原型链
man.__proto__.__proto__.__proto__
实例化对象的隐式原型的隐式原型的隐式原型指向Object的原型对象
- 一个对象如果想使用一个方法或者属性的话他会现在自己本身寻找,没找到的话会向原型对象中查找,如果还没有就会继续向上层的原型对象中擦找,最上层为null,找不到了返回undefined
function Man(name,age,sex){
this.name = name
this.age = age
this.sex = sex
}
var man = new Man(1,2,3) //对象的实例化
//原型对象中的constructor 指向的是构造函数本身
//每个对象下都有一个隐藏的属性 __proto__ (隐式原型) 通过__proto__指向构造函数的prototype(原型对象,显示原型)
console.log(man.__proto__=== Man.prototype)//true
console.log(man.__proto__.__proto__.__proto__.constructor)//Object
```js
Object.prototype.goHome = function(){
console.log('我要去曲江,我要回寒窑')
}
function Man(name,age,sex) {
this.name = name
this.age = age
this.sex = sex
}
// Man函数 也同样看作是对象
var 平贵 = new Man('平贵',40,'男')
// 平贵.goHome()
// Man.goHome()
console.log(Man.__proto__.constructor) //Man的构造函数是Function
console.log(Man.__proto__.__proto__.constructor)
//函数的方法也可以使用原型链找到Object.原型对象下的方法
内置对象
Math 数学对象常用方法
- Math.abs() 绝对值
- Math.random() 随机数
- Math.floor() 向下取整
- Math.round() 向上取整
- Math.ceil() 取整
- Math.sign() 函数返回一个数字的符号, 指示数字是正数,负数还是零
- Math.min() 最小值
- Math.max() 最大值
字符串对象
- substring():截取字符串
- .substr()参数1表示开始索引(负数则从后往前数),参数2表示截取长度。
- split():根据分隔符(参数)将字符串拆分为数组,参数1表示分隔符,参数2表示返回数组的长度
- tirm():去除字符串的前后空格,并返回结构
- replace():字符串查找并替换,返回新的字符串
- match():查找字符,并返回数组,其中存放与之匹配的文本信息
- search():检索字符串中指定的子字符串
时间对象
创建时间对象
var date1 = new Date();//创建时间对象(获取当前时间)
console.log(date1);
var time2 = new Date('2022-1-9 19:53:34');//创建设置的时间对象(获取设置的时间)
console.log(date2);
获取
getTime() 获取距离1970/1/1零时的毫秒数和valueOf()方法返回的结果是一致的(时间戳)
getMilliseconds() 获取当前时间毫秒数0-999
getDay() 返回星期几,取值范围是0-6 星期日是0,以此类推
getYear() 返回的是距离1900年的年份(没有实际用途)
getFullYear() 返回年份
getMonth() 返回月份,取值范围是0-11,0代表一月,以此类推
getDate() 获取当前时间点的日期(天)
getHours() 获取小时0-23
getMinutes() 获取分钟0-59
getSeconds() 获取秒数0-59
getMilliseconds() 获取毫秒数0-999
设置
setMilliseconds() 获取当前时间毫秒数0-999
setDay() 返回星期几,取值范围是0-6 星期日是0,以此类推
setYear() 返回的是距离1900年的年份(没有实际用途)
setFullYear() 返回年份
setMonth() 返回月份,取值范围是0-11,0代表一月,以此类推
setDate() 获取当前时间点的日期(天)
setHours() 获取小时0-23
setMinutes() 获取分钟0-59
setSeconds() 获取秒数0-59
setMilliseconds() 获取毫秒数0-999
DOM节点Api
- DOM 文档对象模型
-
//查 // 分清楚具体节点和节点的集合 document.querySelector() 获取具体节点 document.querySelectorAll() 获取全部节点 document.getElementById() 获取id名匹配的节点 node.children 获取所有子集 node.parentNode 获取父级 node.nextElementSibling 获取上一个兄弟集 node.previousElementSibling 获取下一个兄弟集 node.lastElementChild node.firstElementChild node[0] node[node.length-1] node.querySelector() node.getElementById() node.getAttribute() // 改 node.setAttribute() node.内置属性名 //查改 node.className //查改 node.innerHTML //查改 node.innerText //查改 node.value //查改 // 增 document.createElement() //创建元素 node.appendChild() node.insertBefore('插入的元素',参考元素) node.innerHTML node.cloneNode()//克隆节点 // 删 node.removeChild() node.remove() node.removeAttribute()//删除自定义属性