JavaScript学习笔记
Seven的JavaScript学习笔记
JavaScript是什么
是一种运行在客户端的脚本语言(不需要编译,运行过程中由js解释器逐行解释并执行),主要用于网页的前端验证(检查用户输入的内容是否符合一定的规则)。js代码逐行执行。
js作用
-
表单动态校验(密码强度检测)
-
网页特效
-
服务端开发(Node.js)
-
桌面程序(Electron)
-
app(cordova)
-
控制硬件-物联网(ruff)
-
游戏开发(cocos2d-js)
html/css/js关系
js:实现业务逻辑和页面控制(决定功能)。
js的组成
-
ECAMScirpt:js语法
-
DOM:页面文档对象模型
-
BOM:浏览器对象模型
1.ECAMScript
包括网景公司的JavaScript和微软的Jscript。它规定了js的编程语法和基础核心知识,是所有浏览器厂商共同遵循的一套js语法工业标准。
2.DOM
文档对象模型,是处理可扩展标记语言的标准编程接口。通过dom提供的接口可以对页面上的各种元素进行操作。
3.BOM
浏览器对象模型,提供了独立于内容的、可与浏览器窗口进行互动的对象结构。通过bom可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等。
js的三种书写方法(同css)
行内式
<input type="button" value="suger" onclick"alert('yes')">
-
可以将单行或少量js代码写在html标签的事件属性中(以on开头的)
-
在js中我们推荐使用单引号‘’,html中推荐使用双引号“”
-
可读性差,引号易错(多层嵌套匹配时容易弄混)
-
特殊情况下使用
嵌入式
<script>
alery('hello world');
</script>
外部式
<script src="my.js"></script>
-
利于html页面代码结构化
-
适合js代码量较大情况
-
script标签中间不可以写代码
js常用输入输出语句
-
alert(''message') ; 浏览器弹出警示框 ,输出的,展示给用户的
-
console.log('message') ;浏览器控制台打印输出信息,控制台输出是程序员自己看的
-
prompt('information');浏览器弹出输入框,用户可以输入
以上语句都归属于浏览器
console.log输出可以 :console.log(变量名1,变量名2,···)
prompt用法
prompt获取的内容都为字符串类型
let name = prompt('请输入姓名');//将用户输入存入name变量中
alert(name);//弹出刚刚用户输入的信息(弹出name)
严格检查模式 ‘use strict’
'use strict':严格检查模式,预防js的随意性导致的一些问题
必须写在js的第一行!
前提:idea需要设置支持es6语法
变量的使用
声明变量
age = 1;//声明一个全局变量age,值为1.
var age0;//声明一个age0的变量
let age1;//声明一个age1的块变量(es6新出现,现在多用let)
var name1 = 'gao',
name2 = 'zhang',
age2 = 10;//声明多个变量
Js是一种弱类型语言(动态语言),所有不用提前声明变量类型,程序运行过程中会自动确定。
变量命名规则
变量名字母、数字、下划线或$开头,严格区分大小写,不能是关键字
更新变量
一个变量被重新赋值后,原有值被覆盖,以最后一个值为准
let的基本用法
ES6 新增了let
命令,用来声明变量。它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。局部变量用let
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
上面代码在代码块之中,分别用let
和var
声明了两个变量。然后在代码块之外调用这两个变量,结果let
声明的变量报错,var
声明的变量返回了正确的值。这表明,let
声明的变量只在它所在的代码块有效。
for
循环的计数器,就很合适使用let
命令。
for (let i = 0; i < 10; i++) {
// ...
}
console.log(i);
// ReferenceError: i is not defined
上面代码中,计数器i
只在for
循环体内(也就是花括号{}内部)有效,在循环体外引用就会报错。
下面的代码如果使用var
,最后输出的是10
。
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
上面代码中,变量i
是var
命令声明的,在全局范围内都有效,所以全局只有一个变量i
。每一次循环,变量i
的值都会发生改变,而循环内被赋给数组a
的函数内部的console.log(i)
,里面的i
指向的就是全局的i
。也就是说,所有数组a
的成员里面的i
,指向的都是同一个i
,导致运行时输出的是最后一轮的i
的值,也就是 10。
如果使用let
,声明的变量仅在块级作用域内有效,最后输出的是 6。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
上面代码中,变量i
是let
声明的,当前的i
只在本轮循环有效,所以每一次循环的i
其实都是一个新的变量,所以最后输出的是6
。你可能会问,如果每一轮循环的变量i
都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i
时,就在上一轮循环的基础上进行计算。
另外,for
循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc
上面代码正确运行,输出了 3 次abc
。这表明函数内部的变量i
与循环变量i
不在同一个作用域,有各自单独的作用域(同一个作用域不可使用 let
重复声明同一个变量)。
let不存在变量提升,不允许重复声明,存在暂时性死区。详见ES6 入门教程
let和var区别
-
作用域不同。var是函数作用域,let是块作用域。
-
let不能在定义之前访问该变量,但是var可以。
-
let不能被重新定义,但是var是可以的
js中的数据
数据分为基本数据类型和引用数据类型
-
引用数据类型(复杂数据类型)
-
基本数据类型(简单数据类型)
-
number数值类型(js不区分小数和整数)
- 特殊值:infinity无穷大 -infinity无穷小 NaN非数值
-
string字符串类型(所用装在引号内的内容都是这个类型)
-
布尔类型
-
空类型
-
undefined(变量定义了,但是没有赋值:没有值)
-
null(定义了,赋值为null:有值)
-
-
可以用typeof 变量名
来进行数值类型检测,返回结果为该变量的数据类型
注意:null类型返回的值是object
判断数字类型也可以通过看控制台里面的文字颜色判断。
-
number类型 字为蓝色
-
string类型 字为黑色
-
Boolean类型 true或false为深蓝色
-
undefined和null类型为浅灰色
js数据类型转换
转数字
-
number();整体不可以转换成一个合法数字时返回NaN
-
parseInt();把要转换的内容一位一位查看,只有第一位不是合法数字时出现NaN,否则保留前面的数字值。
-
parseFloat();与parseInt()相同,但是可以解析到小数部分
-
隐式转换(利用算术运算转为数值型) e.g '12'-0即可把字符串型12转为数值型
转字符串
-
string();
-
tostring();括号内不写内容 用法:变量.toString();
-
加号拼接字符串(隐式转换)原理:和字符串拼接的结果都是字符串 用法:变量+'字符串'
转布尔
- boolean();只有0,NaN,空字符串,undefined和null会转成false,其他都是true
比较运算符
-
= 赋值
-
== 等于(类型不一样,值一样,也为true)
-
=== 绝对等于(类型和值都一样才为true)
NaN与所有的数值都不相等,包括自己。只能通过isNaN(NaN)来判断这个数是否是NaN(是数字返回true)
浮点数问题
console.log((1/3) === (1-2/3));
结果为false。因为存在精度问题。所以尽量避免使用浮点数进行运算
可以使用toFixed方法
数组
js中数组值不需要是相同类型的对象
var arr = [1,2,'hi',null]
当取数组下标越界时,会出现undefined
- 长度
arr.length
注意:假如给arr.length
赋值,数组大小就会发生变化。如果赋值变大,多出来的部分为undefinded;如果赋值过小,元素就会丢失
indexOf()
通过元素获取下标
注意:字符串的“1”和数字 1 是不同的。如果不存在返回-1
-
slice()
截取数组的一部分,返回一个新数组。类似string中的substring()
(也是包头不包尾) -
push()
,pop()
尾部
arr.push('a','b');//把a,b加入到数组的尾部
arr.pop();//弹出尾部的一个元素
unshift()
,shift()
头部
arr.unshift('a','b');//把a,b加入到数组的头部
arr.shift();//弹出头部的一个元素
-
排序
arr.sort()
-
元素反转
arr.reverse()
-
concat()
['c','b','a']
arr.concat([1,2,3]);
['c','b','a',1,2,3]
arr
['c','b','a']
注意:concat并没有修改数组,只是返回一个新的数组(如果想保存这个返回的新数组,可以用另一个数组装这个返回的数组arr2=arr.concat([1,2,3]);
)
- 连接符
join
打印并用连接符拼接数组
['c','b','a']
arr.join('-');
"c-b-a"
- 多维数组
arr = [[1,2],[3,4],[5,6]];
arr[1][1];
4
对象
js中所有的键都是字符串,值是任意对象
person['age']//结果为3
对象是花括号,数组是中括号, 每个属性之间使用逗号隔开
var person = {
name:"ming",
age:3,
hobby:['js','html','css']
}
对象赋值(直接赋值)
person.name = "hong"
取对象的值
person.name
> "ming"
person.age
> 3
使用一个不存在的对象属性不会报错
person.haha//会出现一个undefined
动态的删减属性(通过delete)
delete person.name//删除了person的name属性,在控制台中返回一个true
动态的添加(直接给新的属性添加值即可)
person.haha = "haha"
判断属性值是否在这个对象中(xxx in xxx)
'age' in person
true
//继承了父类的toString方法
'toString' in person
true
判断一个属性是否是这个对象自身拥有的( hasOwnProperty() )
person.hasOwnProperty('toString')
false
person.hasOwnProperty('age')
true
字符串
- 转义字符
\n 换行 \b 空格
\t tab \\ 斜杠 \" 双引号
\u4e2d \u#### Unicode字符
\x41 Ascll字符
- 多行字符串编写(用``包裹)
var msg =
` hello
world
!!!!! `
- 模板字符串
let name = "ming";
let age = 3;
let msg = `你好,${name}`
输出结果为 你好,ming
- 字符串长度
var student = "student";
console.log(student.lenth)
-
字符串可变性(不可变?)
-
大小写转换
//注意这里是方法,不是属性
student.toUpperCase();
student.toLowerCase();
- 获取下标
注意:js不区分字符和字符串,字符就是长度为1的字符串
student.indexOf('s')
- 截取
student.substring(1);//从第1个字符截取到最后一个字符 tudent
student.substring(1,3);//[1,3)包头不包尾 tu
- 字符串引号嵌套(外单内双或外双内单)
因为js对引号的匹配遵循就近原则,所以文字内加引号时要遵循外单内双或外双内单
- 字符串拼接用+号
console.log('hello' + '!!')
注意:拼接前会把与字符串相加的任何类型转成字符串类型,再拼成一个新的字符串。
var name;
console.log(name+'名字');
//最后结果为 undefined名字(undefined变为一个字符串和姓名显示在控制台里)
流程控制
if判断
var age = 3;
if ( age > 3 ){
alert('haha');
}else if ( age < 3 ){
alert('kuku');
}else{
alert('xixi');
}
while循环,注意避免程序死循环
var age = 3;
while ( age < 10 ){
age = age + 1;
console.log(age);
}
do{
age = age + 1;
console.log(age);
}while( age < 10 )
for循环
for( let i = 0 ; i < 10 ; i++ ){
console.log(i);
}
forEach循环
var age = [1,12,123,1234]
age.forEach(e=>{console.log(e)})//写法1
age.forEach(function (value){ //写法2
console.log(value)
})
for...in(其实我没搞懂这啥)
解释性语言和编译型语言
都是将程序语言翻译成机器语言的工具(翻译器),区别在于翻译的时间点不同
-
编译器在代码执行之前进行编译,生成中间代码文件 java
-
解释器在运行时进行及时解释,并立即执行(边解释边执行) js
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!