目录
一、初识 JavaScript
1.1 JavaScript 是什么?
1.2 发展历史
1.3 JavaScript 和 HTML 和 CSS 之间的关系
1.4 JavaScript 运行过程
1.5 JavaScript 的组成
二、前置知识
2.1 第一个程序
2.2 JavaScript 的书写形式
2.3 输入输出
三、语法概览
3.1 变量的使用
3.2 理解动态类型
3.3 基本数据类型
string 字符串类型
转义字符
求长度
字符串拼接
boolean 布尔类型
undefined 未定义数据类型
null 空值类型
新增数组元素
四、函数
4.1 语法格式
4.2 关于参数个数
4.3 函数表达式
4.4 作用域
4.5 作用域链
五、对象
JavaScript 的对象和 Java 的对象的区别
一、初识 JavaScript
1.1 JavaScript 是什么?
- 是世界上最流行的编程语言之一
- 是一个脚本语言, 通过解释器运行
- 主要在客户端(浏览器)上运行, 现在也可以基于 node.js 在服务器端运行
JavaScript 最初只是为了完成简单的表单验证(验证数据合法性), 结果后来不小心就火了.
- 网页开发(更复杂的特效和用户交互)
- 网页游戏开发
- 服务器开发(node.js)
- 桌面程序开发(Electron, VSCode 就是这么来的)
- 手机 app 开发
1.2 发展历史
1995 年, JavaScript 之父 布兰登 * 艾奇 (Brendan Eich)
用 10 天时间完成 JS 的设计 ( 由于设计时间太短,语言的一些细节考虑得不够严谨,导致后来很长一段时间, Javascript 写出来的程序混乱不堪 )最初在网景公司 , 命名为 LiveScript, 一般认为,当时 Netscape 之所以将 LiveScript 命名为 JavaScript ,是因为 Java 是当时最流行的 编程语言,带有 "Java" 的名字有助于这门新生语言的传播。 其实 Java 和 JavaScript 之间的语法风格相去甚远 .
JavaScript 发展历史可以参考阮一峰大神的博客http://www.ruanyifeng.com/blog/2011/06/birth_of_javascript.html
1.3 JavaScript 和 HTML 和 CSS 之间的关系
- HTML: 网页的结构(骨)
- CSS: 网页的表现(皮)
- JavaScript: 网页的行为(魂)
HTML用于控制网页的结构,CSS用于控制网页的外观,JavaScript控制的是网页的行为。
很多同学可能不太清晰的了解这三者的关系。
HTML-----超文本标记语言,HTML是一门描述性语言。
CSS----层叠样式表,是用来控制网页外观的一种技术。
JavaScript----是一种嵌入到HTML页面中的语言,由浏览器一边解释一边执行。
我们用一种比喻来说明:咱们把制作网页来比作盖房子。
HTML就相当于钢筋水泥做出来的结构。
CSS比作粉刷、贴瓷砖等装修。
JavaScript就好比给房子通电,你按一下灯泡的开关,灯就亮了。
所以说:HTML用于控制网页的结构,CSS用于控制网页的外观,而JavaScript控制着网页的行为。
通过大脑的想像,大家对这三者的关系就有了更清晰的认知。
甚至你也可以想象这三者的关系是一只小鸟,HTML是没毛的鸟,加上CSS鸟就有了漂亮的羽毛,最后JavaScript就能让鸟儿飞起来。
在理解这三者关系后,熟悉基础语法,就能够编写静态页面了。
版权声明:此段为CSDN博主「爱学习滴小可桢」的原创文章
1.4 JavaScript 运行过程
- 编写的代码是保存在文件中的, 也就是存储在硬盘(外存上).
- 双击 .html 文件浏览器(应用程序)就会读取文件, 把文件内容加载到内存中(数据流向: 硬盘 => 内存)
- 浏览器会解析用户编写的代码, 把代码翻译成二进制的, 能让计算机识别的指令(解释器的工作)
- 得到的二进制指令会被 CPU 加载并执行(数据流向: 内存 => CPU)
- 渲染引擎: 解析 html + CSS, 俗称 "内核"
- JS 引擎: 也就是 JS 解释器. 典型的就是 Chrome 中内置的 V8
1.5 JavaScript 的组成
但是要想完成更复杂的任务 , 完成和浏览器以及页面的交互 , 那么久需要 DOM API 和 BOM API. 这主要指在浏览器端运行的 JS. 如果是运行在服务端的 JS , 则需要使用 node.js 的 API,就不太需要关注 DOM 和 BOM
啥叫标准 ? 车同轨 , 书同文 . 秦始皇最大的贡献之一 , 就是制定了一套标准 .三流公司做产品 , 一流公司做标准 .
二、前置知识
2.1 第一个程序
<script>
alert("你好!");
</script>
JavaScript 代码可以嵌入到 HTML 的 script 标签中 .
2.2 JavaScript 的书写形式
<input type="button" value="点我一下" onclick="alert('haha')">
注意, JS 中字符串常量可以使用单引号表示, 也可以 使用双引号表示.
<script>
alert("haha");
</script>
2.2.3 外部式
<script src="hello.js"></script>
alert("hehe");
注意, 这种情况下 script 标签中间不能写代码. 必须空着(写了代码也不会执行).
// 我是单行注释
/*
我是多行注释
我是多行注释
我是多行注释
*/
使用 ctrl + / 切换注释 .多行注释不能嵌套 . 形如这种代码就会报错
2.3 输入输出
// 弹出一个输入框
prompt("请输入您的姓名:");
输出: alert
弹出一个警示对话框, 输出结果
// 弹出一个输出框
alert("hello");
输出: console.log
// 向控制台输出日志
console.log("这是一条日志");
注意: 在 VSCode 中直接输入 "log" 再按 tab 键, 就可以快速输入 console.log
需要打开浏览器的开发者工具 (F12) => Console 标签页 才能看到结果 .
去医院看病 , 医生会让患者做各种检查 , 血常规 , 尿常规 , B 超 , CT 等 ... 此时得到一堆检测结果 . 这些结果普通人看不懂, 但是医生能看懂 , 并且医生要通过这些信息来诊断病情 .这些检测结果就是医生的 " 日志 "PS: 相比于医生来说 , 程序猿多一个终极大招 , " 重启下试试 ".
console 是一个 js 中的 " 对象 ". 表示取对象中的某个属性或者方法 . 可以直观理解成 " 的 "console.log 就可以理解成 : 使用 " 控制台 " 对象 " 的 " log 方法 .
三、语法概览
JavaScript 虽然一些设计理念和 Java 相去甚远, 但是在基础语法层面上还是有一些相似之处的.
3.1 变量的使用
var 是 JS 中的关键字 , 表示这是一个变量 .= 在 JS 中表示 " 赋值 ", 相当于把数据放到内存的盒子中 . = 两侧建议有一个空格每个语句最后带有一个 ; 结尾 . JS 中可以省略 ; 但是建议还是加上 .注意 , 此处的 ; 为英文分号 . JS 中所有的标点都是英文标点 .初始化的值如果是字符串 , 那么就要使用单引号或者双引号引起来 .初始化的值如果是数字 , 那么直接赋值即可 .
console.log(age); // 读取变量内容
age = 30; // 修改变量内容
为啥动漫中的角色都是要先喊出技能名字再真正释放技能 ?就是因为变量要先声明才能使用 .
var name = prompt("请输入姓名:");
var age = prompt("请输入年龄:");
var score = prompt("请输入分数");
alert("您的姓名是: " + name);
alert("您的年龄是: " + age);
alert("您的分数是: " + score);
var name = prompt("请输入姓名:");
var age = prompt("请输入年龄:");
var score = prompt("请输入分数");
alert("您的姓名是: " + name + "\n" + "您的年龄是: " + age + "\n" + "您的分数是: " +
score + "\n");
3.2 理解动态类型
1) JS 的变量类型是程序运行过程中才确定的(运行到 = 语句才会确定类型)
var a = 10; // 数字
var b = "hehe"; // 字符串
2) 随着程序运行, 变量的类型可能会发生改变.
var a = 10; // 数字
a = "hehe"; // 字符串
这一点和 C Java 这种静态类型语言差异较大.
C, C++, Java, Go 等语言是静态类型语言 . 一个变量在创建的时候类型就确定了 , 不能在运行时发生改变. 如果尝试改变, 就会直接编译报错 .
3.3 基本数据类型
- number: 数字. 不区分整数和小数.
- boolean: true 真, false 假.
- string: 字符串类型.
- undefined: 只有唯一的值 undefined. 表示未定义的值.
- null: 只有唯一的值 null. 表示空值.
number 数字类型
JS 中不区分整数和浮点数, 统一都使用 "数字类型" 来表示.
var a = 07; // 八进制整数, 以 0 开头
var b = 0xa; // 十六进制整数, 以 0x 开头
var c = 0b10; // 二进制整数, 以 0b 开头
- Infinity: 无穷大, 大于任何数字. 表示数字已经超过了 JS 能表示的范围.
- -Infinity: 负无穷大, 小于任何数字. 表示数字已经超过了 JS 能表示的范围.
- NaN(Not a Number): 表示当前的结果不是一个数字.
var max = Number.MAX_VALUE;
// 得到 Infinity
console.log(max * 2);
// 得到 -Infinity
console.log(-max * 2);
// 得到 NaN
console.log('hehe' - 10);
注意:
1. 负无穷大 和 无穷小 不是一回事 . 无穷小指无限趋近与 0, 值为 1 / Infinity2. 'hehe' + 10 得到的不是 NaN, 而是 'hehe10', 会把数字隐式转成字符串 , 再进行字符串拼接 .3. 可以使用 isNaN 函数判定是不是一个非数字 .console.log(isNaN(10)); // false console.log(isNaN('hehe' - 10)); // true
string 字符串类型
var a = "haha";
var b = 'hehe';
var c = hehe; // 运行出错
如果字符串中本来已经包含引号咋办?
var msg = "My name is "zhangsan""; // 出错
var msg = "My name is \"zhangsan\""; // 正确, 使用转义字符. \" 来表示字符串内部的引
号.
var msg = "My name is 'zhangsan'"; // 正确, 搭配使用单双引号
var msg = 'My name is "zhangsan"'; // 正确, 搭配使用单双引号
转义字符
- \n
- \\
- \'
- \"
- \t
求长度
var a = 'hehe';
console.log(a.length);//4
var b = '哈哈';
console.log(b.length);//2
//单位为字符的数量
字符串拼接
var a = "my name is ";
var b = "zhangsan";
console.log(a + b);
注意, 数字和字符串也可以进行拼接
var c = "my score is ";
var d = 100;
console.log(c + d);
注意, 要认准相加的变量到底是字符串还是数字
console.log(100 + 100); // 200
console.log('100' + 100); // 100100
boolean 布尔类型
boolean 原本是数学中的概念 ( 布尔代数 ).在计算机中 boolean 意义重大 , 往往要搭配条件 / 循环完成逻辑判断 .
console.log(true + 1);
console.log(false + 1)
这样的操作其实是不科学的 . 实际开发中不应该这么写 .
undefined 未定义数据类型
var a;
console.log(a)
console.log(a + "10"); // undefined10
console.log(a + 10);
null 空值类型
var b = null;
console.log(b + 10); // 10
console.log(b + "10"); // null10
注意:null 和 undefined 都表示取值非法的情况 , 但是侧重点不同 .null 表示当前的值为空 . ( 相当于有一个空的盒子 )undefined 表示当前的变量未定义 . ( 相当于连盒子都没有 )
JS中的条件语句与Java类似,在此不做过多赘述
新增数组元素
var arr = [9, 5, 2, 7];
arr.length = 6;
console.log(arr);
console.log(arr[4], arr[5]);
var arr = [];
arr[2] = 10;
console.log(arr)
此时这个数组的【0】和【1】都是undefined
var arr = [9, 5, 2, 7, 3, 6, 8];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 != 0) {
newArr.push(arr[i]);
}
}
console.log(newArr);
删除数组中的元素
使用 splice 方法删除元素
var arr = [9, 5, 2, 7];
// 第一个参数表示从下表为 2 的位置开始删除. 第二个参数表示要删除的元素个数是 1 个
arr.splice(2, 1);
console.log(arr);
// 结果
[9, 5, 7]
目前咱们已经用到了数组中的一些属性和方法 .arr.length, length 使用的时候不带括号 , 此时 length 就是一个普通的变量 ( 称为成员变量 , 也叫属性)arr.push(), arr.splice() 使用的时候带括号 , 并且可以传参数 , 此时是一个函数 ( 也叫做方法 )
四、函数
4.1 语法格式
// 创建函数/函数声明/函数定义
function 函数名(形参列表) {
函数体
return 返回值;
}
// 函数调用
函数名(实参列表) // 不考虑返回值
返回值 = 函数名(实参列表) // 考虑返回值
-
函数定义并不会执行函数体内容 , 必须要调用才会执行 . 调用几次就会执行几次 .
-
function hello() { console.log("hello"); } // 如果不调用函数, 则没有执行打印语句 hello();
- 调用函数的时候进入函数内部执行, 函数结束时回到调用位置继续执行. 可以借助调试器来观察.
- 函数的定义和调用的先后顺序没有要求. (这一点和变量不同, 变量必须先定义再使用)
// 调用函数
hello();
// 定义函数
function hello() {
console.log("hello");
}
4.2 关于参数个数
实参和形参之间的个数可以不匹配. 但是实际开发一般要求形参和实参个数要匹配
sum(10, 20, 30); //30
sum(10); // NaN, 相当于 num2 为 undefined.
JS 的函数传参比较灵活 , 这一点和其他语言差别较大 . 事实上这种灵活性往往不是好事 .
4.3 函数表达式
var add = function() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
console.log(add(10, 20)); // 30
console.log(add(1, 2, 3, 4)); // 10
console.log(typeof add); // function
// 全局变量
var num = 10;
console.log(num);
function test() {
// 局部变量
JS 中函数是一等公民 , 可以用变量保存 , 也可以作为其他函数的参数或者返回值 .
4.4 作用域
// 全局变量
var num = 10;
console.log(num);
function test() {
// 局部变量
console.log(num);
}
function test2() {
// 局部变量
var num = 30;
console.log(num);
}
test();
test2();
console.log(num);
// 执行结果
10
20
30
10
if (1 < 2) {
var a = 10;
}
console.log(a);
4.5 作用域链
背景:
- 函数可以定义在函数内部
- 内层函数可以访问外层函数的局部变量.
var num = 1;
function test1() {
var num = 10;
function test2() {
var num = 20;
console.log(num);
}
test2();
}
test1();
// 执行结果
20
五、对象
" 电脑 " 不是对象 , 而是一个泛指的类别 . 而 " 我的联想笔记本 " 就是一个对象 .
- 属性: 事物的特征.
- 方法: 事物的行为.
例如表示一个学生信息 . ( 姓名蔡徐坤 , 身高 175cm, 体重 170 斤 )var student = [' 蔡徐坤 ', 175, 170];但是这种情况下到底 175 和 170 谁表示身高 , 谁表示体重 , 就容易分不清
var a = {}; // 创建了一个空的对象
var student = {
name: '蔡徐坤',
height: 175,
weight: 170,
sayHello: function() {
console.log("hello");
}
};
- 使用 { } 创建对象
- 属性和方法使用键值对的形式来组织.
- 键值对之间使用 , 分割. 最后一个属性后面的 , 可有可无
- 键和值之间使用 : 分割.
- 方法的值是一个匿名函数.
// 1. 使用 . 成员访问运算符来访问属性 `.` 可以理解成 "的"
console.log(student.name);
// 2. 使用 [ ] 访问属性, 此时属性需要加上引号
console.log(student['height']);
// 3. 调用方法, 别忘记加上 ()
student.sayHello();
2. 使用 new Object 创建对象
var student = new Object(); // 和创建数组类似
student.name = "蔡徐坤";
student.height = 175;
student['weight'] = 170;
student.sayHello = function () {
console.log("hello");
}
console.log(student.name);
console.log(student['weight']);
student.sayHello();
注意, 使用 { } 创建的对象也可以随时使用 student.name = "蔡徐坤"; 这样的方式来新增属性.
var mimi = {
name: "咪咪",
type: "中华田园喵",
miao: function () {
console.log("喵");
}
};
var xiaohei = {
name: "小黑",
type: "波斯喵",
miao: function () {
console.log("猫呜");
}
}
var ciqiu = {
name: "刺球",
type: "金渐层",
miao: function () {
console.log("咕噜噜");
}
}
此时写起来就比较麻烦. 使用构造函数可以把相同的属性和方法的创建提取出来, 简化开发过程.
function 构造函数名(形参) {
this.属性 = 值;
this.方法 = function...
}
var obj = new 构造函数名(实参);
注意:
- 在构造函数内部使用 this 关键字来表示当前正在构建的对象.
- 构造函数的函数名首字母一般是大写的.
- 构造函数的函数名可以是名词.
- 构造函数不需要 return
- 创建对象的时候必须使用 new 关键字.
function Cat(name, type, sound) {
this.name = name;
this.type = type;
this.miao = function () {
console.log(sound); // 别忘了作用域的链式访问规则
}
}
var mimi = new Cat('咪咪', '中华田园喵', '喵');
var xiaohei = new Cat('小黑', '波斯喵', '猫呜');
var ciqiu = new Cat('刺球', '金渐层', '咕噜噜');
console.log(mimi);
mimi.miao();
理解 new 关键字
JavaScript 的对象和 Java 的对象的区别
在 ES6 中也引入了 class 关键字 , 就能按照类似于 Java 的方式创建类和对象了 .
例如 :在 Java 中已经学过 ArrayList 和 LinkedList. 为了让程序猿使用方便 , 往往写作List<String> list = new ArrayList<>()然后我们可以写一个方法 :void add ( List < String > list , String s ) {list . add ( s );}我们不必关注 list 是 ArrayList 还是 LinkedList, 只要是 List 就行 . 因为 List 内部带有 add 方法 .当我们使用 JavaScript 的代码的时候function add ( list , s ) {list . add ( s )}add 对于 list 这个参数的类型本身就没有任何限制 . 只需要 list 这个对象有 add 方法即可 . 就不必像 Java 那样先继承再重写绕一个圈子 .