JavaScript基础语法
1. JavaScript 是什么?
JavaScript (简称 JS) 是世界上最流行的编程语言之一
是一个脚本语言, 通过解释器运行
主要在客户端(浏览器)上运行, 现在也可以基于 node.js 在服务器端运行.
JavaScript 最初只是为了完成简单的表单验证(验证数据合法性), 结果后来不小心就火了.
当前 JavaScript 已经成为了一个通用的编程语言 JavaScript 的能做的事情:
网页开发(更复杂的特效和用户交互)
网页游戏开发 服务器开发(node.js)
桌面程序开发(Electron, VSCode 就是这么来的)
手机 app 开发
JavaScript是布兰登等人用十天做出来的,所以一些语法上有一些混乱,这也很正常
与Java语法风格相差甚远,JavaScript原名LiveScript,当时Java很火,这样改可以促进新生语言的传播
所以后来火了,火狐公司就推出了JavaScript的手册了
后续讲解的内容,只是常用的,如果有特殊要求,可以去下面两个链接里去研究,并且支持在线运行!
传送门:手册
mdn主页:[主页](MDN Web Docs (mozilla.org))
如果不走前端方向,我们只需要简单的扫盲还有知道简单的语法就行了
JavaScript很佛系,等一下你就知道了,很多地方,即使你故意写错,它也不会觉得你错,还是会给你个结果,但是只要你正常地去写,其实也不会怎么样
JavaScript发展史:一位大神的博客
JS与HTML和CSS的关系
如果把页面比作人的话,HTML就是骨架,CSS就是皮肤等器官,JS就是灵魂
HTML:网页的结构
CSS:网页的表现
JS:网页的行为
JS是前后端之间的桥梁,只有JS能从数据库里获取到活数据传给前端
JS怎么运行的?
JS的指令和HTML,CSS的都会被转化为机器能看懂的二进制指令(即硬盘=>内存),由浏览器解析,CPU执行
浏览器分为两种引擎:
渲染引擎: 解析html和css,俗称“内核”
从内核不是计算机内核,是浏览器内部核心引擎
JS引擎: JS解析器,Chrome中内置的是V8
JavaScript 的组成
ECMAScript(简称 ES): JavaScript 语法
DOM: 页面文档对象模型, 对页面中的元素进行操作
BOM: 浏览器对象模型, 对浏览器窗口进行操作
光有 JS 语法, 只能写一些基础的逻辑流程.
但是要想完成更复杂的任务, 完成和浏览器以及页面的交互, 那么久需要 DOM API 和 BOM API.
这主要指在浏览器端运行的 JS. 如果是运行在服务端的 JS , 则需要使用 node.js 的 API, 就不太需要关注 DOM 和 BOM
重要概念: ECMAScript
这是一套 “标准”, 无论是啥样的 JS 引擎都要遵守这个标准来实现.
Chrome浏览器如果没取消自动更新,会在后台帮你更新这个版本,所以你现在应该用的是最新的
2. JavaScript的基础语法
2.1 JS的三种写法
JS是要作用在HTML上的script标签的,依托html文件而存在
请大家自行创建
2.1.1 行内式
<input type="button" value="点我一下" onclick="alert('helloWorld');">
点击这个按钮,就可以触发onclick的JS语句,其实在任意html元素都可以,只要点到这个“html元素盒子”,就会触发
alert就是弹出显示的意思,就像下面的那样弹出一个框!
MySQL里用,alter去修改字段,拼写相似,请勿混淆
注意, JS 中字符串常量可以使用单引号表示, 也可以 使用双引号表示.
比如双引号里有双引号的话,就会冲突!
HTML 中推荐使用双引号, JS 中推荐使用单引号>
效果:
在JS的学习和使用中,常常要用到浏览器的开发者工具(F12)
控制台和源代码是我们经常要用到的
我们可以在这里输入js代码,js断点调试,语法错误,报错信息提醒…
了解和会使用一点点就行了
百度网站有一个小彩蛋:
元素按钮则是查看HTML元素在页面中的位置,属性等等…
箭头按钮则是通过箭头去选中HTML元素进行观察
网络按钮是抓包用的,http时会将抓包,但是也不常用浏览器抓,用fiddler
比如刚才的双引号和单引号的问题,这里演示个双引号冲突的例子:
<input type="button" value="点我一下" onclick="alert("helloWorld");">
点击链接跳转:
不弹框,在控制台输出文字:
<input type="button" value="点我一下" onclick="console.log('helloConsole');">
1
console就是JavaScript的控制台对象,log就是打印日志的意思
效果:
不更改文件内容,在控制台里输入JavaScript语句(理论上是在更改这个临时的文件,刷新就恢复了)
对于源代码强大的调试功能,随后解释~
2.1.2 内嵌式写法
就是写到html的script标签中,这对标签之中就代表js代码
这个标签不会展示在页面中
<script> alert("helloWorld"); //弹出一个框 //js的注释跟java是一样的,//为行注释 /**/为块注释 </script>
那么这个标签的位置应该放在哪呢?
建议:放在body的结束位置之前
原因:
html的编译是从上到下的,如果js代码获取html中的标签元素的时候,该元素未被初始化,就会出错
写在最后,保证js能获取到所有的标签元素
区别于css,style标签放哪都一样,页面最终呈现是层叠+优先级来的,而不是执行先后
script标签的位置放太前的错误案例:
用到一些js语法,现在先看着,不需要理解,后面会讲
大概意思就是,通过document(本文件对象),再通过id获取标签元素对象,的属性value的值,并将它alert,并且这是在head里
效果:
如果是在body结束之前,则不会有事
在控制台输入也行,其实控制台输入的js代码就是在所有标签执行完后执行的
遇到错误不要着急,用开发者工具的调试功能:
同样的可以打断点,同样的可以一步一步走(右侧)
刷新一下,下一次就会跳到这个端点了~
2.1.3 外部写法
外部外部,就是不在html中写,而是在html标签外写,当然html文件中,html标签外不能写东西。我们要自己建立一个js文件,把js代码写在里面,然后引入这个js文件
在js里面就直接写js代码就行了,不需要写标签~
但是我们要在html文件中去引用js文件
用script标签,src属性的值为js文件的地址
代表js的代码被标签包围
为什么建议写在head里?
因为一般用这种写法是引入了外部资源:工具js,也就是说这种js代码,是不会去操控html中特定的标签的,所以跟写在body结束前是没啥区别的
保证后续我们的js代码会被这个工具作用到
你要是外部资源里写一些控制标签的代码,结合实际去放到合适的位置就行了
一般外部资源是不会这样的,因为外部资源也不会事先知道你标签里元素的id等信息呀
顶多提供一些脚本工具之类的
效果:
head里执行了alert,导致只有在点击确认后,才能走下去,此时body还未执行
对于这三种写法:
行内,基本上就是简单的给一个标签添加一点js加持而已
内嵌,在html展示后,可对标签元素进行操作…
外部,引入外部资源,工具js…
根据业务场景选择,虽然他们效果都一样,初心不一样
2.2 输入与输出
输出就是不再讲了,alert和console.log,弹窗和控制台打印日志两种
console.error也是一种输出方式,相当于java的抛异常
log在控制台会自动换行
输入:
这是有返回值的,返回赋值给js的变量,等一下讲~
prompt("请输入你的名字:");
//弹出一个输入框
//js中变量只有一种类型,就是var
var data = prompt("请输入你的名字");
console.error(data);
2.3 JS语法概览
2.3.1 变量
JS里就只有一种类型,就是var,无论你是数字,无论你是字符串,无论你是啥类型,最终还是var这种弱类型
这也导致,一些强制类型转化的规则千奇百怪,语法规则有点混乱
var,定义全局变量的
let,定义局部变量的
两种类型,let是新版本才有的
但是实际上,他们的界限很模糊,并且JS中,由于很混乱的语法规则,导致你怎么写都不怎么报错,包括你模糊全局和局部也不会报错
对于我们前端不专业的人,不需要深度去学习
还是那样子,好好老实按照正常的写法去写代码,不要玩花的,就不会错了
就比如,局部变量,就不要在局部外的地方用了,正常也不会这么写,因为我们本来就知道这样写不对
但是这样写在js中又有令人意料之外的效果
所以学习js,切忌钻牛角尖,大概靠感觉去写就行
语法:
一般浏览器是支持var的,有些未更新的就用不了let
var data = 10;
var doble = 0.618;
var string = "helloWorld";
JS的输出,跟java差不多,不考虑类型(前提知道怎么打印),可以通过+号拼接
2.3.2 var动态类型
JS就这一个类型,var这个弱类型,在浏览器运行的时候需要推断其真实的数据类型
就比如这两个例子:
定义变量的时候是字符串赋值的:
var numb1 = "10";
var numb2 = "20";
alert(numb1 + numb2);
结果:
定义遍历的时候是数字赋值的:
var numb1 = 10;
var numb2 = 20;
alert(numb1 + numb2);
结果:
杂合:
var numb1 = "10";
var numb2 = 20;
alert(numb1 + numb2);
结果:
触发拼接了
对于浏览器是怎么推导类型的,不需要记忆,为了保证万无一失,我会在一些不确定的地方,自主的去类型转化,把命运握在自己手中
还是那句话,老老实实不玩花的
var numb1 = "10";
var numb2 = 20;
alert(parseInt(numb1) + numb2);
2.3.3 基本数据类型
js虽然只有var类型,但是内部而言,它表示的值,应该分为以下几种类型:
number: 数字,整数/小数
boolean: true/false
string: 字符串
undefined: 只有唯一的值:undefined,表示未定义的变量的值
null: 只有唯一的值null,表示定义的变量为空值
你可以理解成,不同的类型实例化了var这个对象,浏览器通过谁实例化的变量,判断类型
例如list由顺序表或者链表实例化,编译器清楚如何其本质是顺序表还是链表
在内存上就展现不同了
内部怎么搞的,我们不需要去研究~
number,分为整数和小数
虽然分的不细,但是在自主类型转化的时候是可以指定转化为int/float的
对于整数,可以用十进制,二进制八进制十六进制等等去表示
但是他们运算或者输出都是以十进制形式的
var numb1 = 0101;//8进制 var numb2 = 0x101;//16进制 var numb3 = 0b101;//2进制 var sum = numb1 + numb2 + numb3; alert(numb1 + '+' + numb2 + '+' + numb3 + '=' + sum);
number类型有几个特殊的取值
infinity:无穷大,大于任何数字,(一个数超过js的表示范围,并不会像c或者java的轮回机制,而是给了一个无穷大的值)
-infinity:负无穷大,小于任何数字
NaN:表示当前的结果不是一个数字
not a number
//js的内置类随便用,不需要导入,一些工具js才需要
var max = Number.MAX_VALUE;//获取最大值
var numb1 = max * 2;
var numb2 = -max * 2;
var numb3 = 'hehe' - 10;//字符串没有减法
alert(max + " " + numb1 + " " + numb2 + " " + numb3);
而混乱的是,如果字符串是“数字字符串”,相减反而不是NaN
毕竟人家制作周期短,多担待点~
var numb1 = "5";
var numb2 = 5;
alert(numb1 - numb2);
最好的处理方法就是,自主类型转化~
var numb1 = "5";
var numb2 = 5;
alert(parseInt(numb1) - numb2);
非数字字符强转后就是NaN
var numb1 = "abc";
alert(parseInt(numb1));
NaN的判断函数:isNaN();
比较绕,是一个数返回false,不是一个数返回true
因为它判断的是你是不是NaN,而不是判断你是不是一个数
var numb1 = "abc";
alert(isNaN(parseInt(numb1)));
2. string
js中不区分字符和字符串,用双引号和单引号都可以,避免出现引号冲突即可
转义字符:
跟c或者java差不多
例如我要打印,你好“世界”
通过两个双引号去解决引号冲突问题
var str = '你好“世界”';
alert(str);
通过转义字符表示双引号
var str = "你好\"世界\"";
alert(str);
再讲一种输出方式,输出到html文件里,用到document.write();
获取document(本文件)对象,进行写操作
这个操作虽然确实影响了页面,但是并没有改变html源码,只是一个后来去修改的脚本
var str = "你好\"世界\"";
document.write(str);
字符串长度:
与java类似(java是length()方法),内部是字符串类型,就有个内部属性length
一个汉字和一个字母都算一个字符
var str = "你好\"世界\"";
document.write(str.length);
boolean 布尔类型
与number进行算术运算的时候,并不是NaN:
而是flase视为0,true视为1
var flag1 = true + 1; var flag2 = false + 1; alert(flag1 + " " + flag2);
布尔类型跟java一样,是逻辑表达式的结果,对于逻辑运算符的细节,稍后讲解
alert(1 + 1 < 3);
undefined 未定义数据类型
变量没有被初始化,就是undefined
毕竟每个变量都是var,没人赋值,它是什么基本数据类型吗?
那么就给他一个“未定义数据类型”
这个变量名得被申明过才行,随便写一个变量名,打印出来不是undefined,而是报错
var a;
alert(a);
可以和字符串进行拼接:
注意,触发拼接的前提是,有至少一个字符串类型
var a;
alert(a + "10");
var a;
alert(a + 10);
null,空值类型
与undefined不同的是,null类型就是一个空值,变量初始化的值就是null
运算:
相当于视为0去计算
OMG,居然不是NaN哈哈
var a = null; alert(a + 10); var a = null; alert(a * 10);
可以进行字符串拼接
var a = null;
alert(a + "10");
注意:
null和undefined都表示异常的值,但是侧重点不一样
null表示值为空
undefined表示连值都没有
2.3.4 运算符
由于编程语言的运算符大部分相似,我只讲js的特别之处
但是由于是弱类型,一些效果也可能不同
记住那句话,别搞花的,自己掌握命运(自主强制类型转化)
特别比较运算符:
===
在java中,不同类型之间不能比较,但是在js中,由于只有一个var类型,所以变量之间都可以比较,但是他们的内部类型则有可能不一样
而==,则会隐式类型转换
区别于“==”,这个运算符不会隐式类型转化
var flag1 = 1 == '1';
var flag2 = 1 === '1';
alert(flag1 + " " + flag2);
!==
同理
var flag1 = 1 != '1';
var flag2 = 1 !== '1';
alert(flag1 + " " + flag2);
但是,js的隐式转化,不靠谱,还是自主强制转化好!
2.3.5 条件语句
==和!=会进行隐式强制类型转化 ===和!===则不会进行隐式强制类型转化 var number = 100; if(number % 2 == 0) { alert("是偶数"); } else { alert("是奇数"); } if(10 == "10") { alert("相等"); } else { alert("不相等"); }
if(10 === "10") { alert("相等"); } else { alert("不相等"); }
一个简单的代码:
用户输入一个数,判断奇偶数
根据刚才的数据类型分析,你注意到了,我们在输入数据的时候,它怎么知道我是字符串呢,还是数字呢,虽然都是var类型
我不想记,我自主强制类型转化,这样靠谱点,这样严谨点就舒服了
输入的时候默认是string
运算的时候帮你转化(什么时候转化呢?),俺也不知道
一些会不会帮你转化呢,不知道~
var number = prompt("请输入一个数字:"); if(parseInt(number) % 2 == 0) { alert("偶数"); }else { alert("奇数"); }
三元表达式也是可以用的
var number = parseInt(prompt("请输入年份:")); alert( number % 400 == 0 || (number % 100 != 0 && number % 4 == 0) ? "是" : "不是" );