JavaScript (简称 JS)
JavaScript 的能做的事情:
编写的代码是保存在文件中的, 也就是存储在硬盘(外存上).
双击 .html 文件浏览器(应用程序)就会读取文件, 把文件内容加载到内存中(数据流向: 硬盘 => 内存)
浏览器会解析用户编写的代码, 把代码翻译成二进制的, 能让计算机识别的指令(解释器的工作)
得到的二进制指令会被 CPU 加载并执行(数据流向: 内存 => CPU)
浏览器分成渲染引擎 + JS 引擎.
<script>
alert("你好!");
</script>
直接嵌入到 html 元素内部
<input type="button" value="点我一下" onclick="alert('haha')">
写到 script 标签中
<script>
alert("haha");
</script>
写到单独的 .js 文件中
<script src="hello.js"></script>
.js文件
alert("hehe");
这种情况下 script 标签中间不能写代码. 必须空着,适合代码多的情况
输入: prompt——弹出一个输入框
// 弹出一个输入框
prompt("请输入您的姓名:");
输出: alert ——弹出一个警示对话框, 输出结果
// 弹出一个输出框
alert("hello");
输出: console.log——在控制台打印一个日志(供程序员看)
// 向控制台输出日志
console.log("这是一条日志");
创建变量(变量定义/变量声明/变量初始化)
var name = 'zhangsan';
var age = 20;
使用变量
console.log(age); // 读取变量内容
age = 30; // 修改变量内容
代码示例: 弹框提示用户输入信息, 再弹框显示
var name = prompt("请输入姓名:");
var age = prompt("请输入年龄:");
var score = prompt("请输入分数");
alert("您的姓名是: " + name + "\n" + "您的年龄是: " + age + "\n" + "您的分数是: " +
score + "\n");
JS 中内置的几种类型:
number 数字类型
特殊的数字值
var max = Number.MAX_VALUE;
// 得到 Infinity
console.log(max * 2);
// 得到 -Infinity
console.log(-max * 2);
// 得到 NaN
console.log('hehe' - 10);
string 字符串类型
字符串字面值需要使用引号引起来, 单引号双引号均可
如果字符串中本来已经包含引号
var msg = "My name is "zhangsan""; // 出错
var msg = "My name is \"zhangsan\""; // 正确, 使用转义字符. \" 来表示字符串内部的引
号.
var msg = "My name is 'zhangsan'"; // 正确, 搭配使用单双引号
var msg = 'My name is "zhangsan"'; // 正确, 搭配使用单双引号
转义字符
有些字符不方便直接输入, 于是要通过一些特殊方式来表示
求长度
var a = 'hehe';
console.log(a.length);
var b = '哈哈';
console.log(b.length); //单位为字符的数量
字符串拼接
使用 + 进行拼接,数字和字符串也可以进行拼接,要认准相加的变量到底是字符串还是数字
boolean 布尔类型
表示 “真” 和 “假”
undefined 未定义数据类型
var a;
console.log(a) //undefined
//undefined 和字符串进行相加, 结果进行字符串拼接
console.log(a + "10"); // undefined10
//undefined 和数字进行相加, 结果为 NaN
console.log(a + 10);
null 空值类型
var b = null;
console.log(b + 10); // 10
console.log(b + "10"); // null10
算术运算符
+ - * /
赋值运算符 & 复合赋值运算符
= += *= /= %=
**自增自减运算符 **
++: 自增1 --: 自减1
**比较运算符 **
>
<=
>=
== 比较相等(会进行隐式类型转换)
!=
=== 比较相等(不会进行隐式类型转换)
!==
逻辑运算符
&& 与: 一假则假
|| 或: 一真则真
! 非
位运算
& 按位与
| 按位或
~ 按位取反
^ 按位异或
**移位运算 **
<< 左移
>> 有符号右移(算术右移)
>>> 无符号右移(逻辑右移)
if 语句
var num = 10;
if (num % 2 == 0) {
console.log("num 是偶数");
} else {
console.log("num 是奇数");
}
//不能写成 num % 2 == 1 就是奇数. 负的奇数 % 2 结果可能是 -1
三元表达式
条件 ? 表达式1 : 表达式2
switch
switch (表达式) {
case 值1:
语句1;
break;
case 值2:
语句2:
break;
default:
语句N;
}
while 循环、continue 、break、for 循环 和C语言类似
创建数组
// 使用 new 关键字创建
// Array 的 A 要大写
var arr = new Array();
//使用字面量方式创建 [常用]
var arr = [];
var arr2 = [1, 2, 'haha', false]; // 数组中保存的内容称为 "元素"
JS 的数组不要求元素是相同类型,这一点和 C, C++, Java 等静态类型的语言差别很大. 但是 Python, PHP 等动态类型语言也是如此
获取数组元素
新增数组元素
//通过修改 length 新增,新增的元素默认值为 undefined
var arr = [9, 5, 2, 7];
arr.length = 6;
//通过下标新增,如果下标超出范围赋值元素, 则会给指定位置插入新元素
var arr = [];
arr[2] = 10;
//此时这个数组的 [0] 和 [1] 都是 undefined
//使用 push 进行追加元素
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]);
}
}
删除数组中的元素
//使用 splice 方法删除元素
var arr = [9, 5, 2, 7];
// 第一个参数表示从下表为 2 的位置开始删除. 第二个参数表示要删除的元素个数是 1 个
arr.splice(2, 1);
console.log(arr);
// 结果
[9, 5, 7]
/ 创建函数/函数声明/函数定义
function 函数名(形参列表) {
函数体
return 返回值;
}
// 函数调用
函数名(实参列表) // 不考虑返回值
返回值 = 函数名(实参列表) // 考虑返回值
函数定义并不会执行函数体内容, 必须要调用才会执行. 调用几次就会执行几次
function hello() {
console.log("hello");
}
// 如果不调用函数, 则没有执行打印语句
hello();
参数个数
函数表达式
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
在 ES6 标准之前, 作用域主要分成两个:
作用域链
在 JS 中, 字符串, 数值, 数组, 函数都是对象.
每个对象中包含若干的属性和方法.
使用 字面量 创建对象 [常用]
使用 { } 创建对象
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();
使用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();
使用构造函数创建对象
前面的创建对象方式只能创建一个对象. 而使用构造函数可以很方便 的创建多个对象
function 构造函数名(形参) {
this.属性 = 值;
this.方法 = function...
}
var obj = 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 关键字
new 的执行过程:
JavaScript 没有 “类” 的概念
对象其实就是 “属性” + “方法” . 类相当于把一些具有共性的对象的属性和方法单独提取了出来 ,在 JavaScript 中的 “构造函数” 也能起到类似的效果,而且即使不是用构造函数, 也可以随时的通过 { } 的方式指定出一些对象
JavaScript 对象不区分 “属性” 和 "方法
JavaScript 中的函数是 “一等公民”, 和普通的变量一样. 存储了函数的变量能够通过 ( ) 来进行调用执行
JavaScript 对象没有 private / public 等访问控制机制
对象中的属性都可以被外界随意访问
JavaScript 对象没有 “继承”
继承本质就是 “让两个对象建立关联”. 或者说是让一个对象能够重用另一个对象的属性/方法.JavaScript 中使用 “原型” 机制实现类似的效果.
JavaScript 没有 “多态”
但是在 JavaScript 中本身就支持动态类型, 程序猿在使用对象的某个方法的时候本身也不需要对对象的类型做出明确区分. 因此并不需要在语法层面上支持多态.
JS 分成三个大的部分
WebAPI 就包含了 DOM + BOM. 所谓的 API 本质上就是一些现成的函数/对象, 让程序猿拿来就用, 方便开发.相当于一个工具箱. 只不过程序猿用的工具箱数目繁多, 功能复杂.
DOM 全称为 Document Object Model.W3C 标准给我们提供了一系列的函数, 让我们可以操作:
这部分工作类似于 CSS 选择器的功能
var element = document.querySelector(selectors);
div class="box">abc</div>
<div id="id">def</div>
<h3><span><input type="text"></span></h3>
<script>
var elem1 = document.querySelector('.box');
console.log(elem1);
var elem2 = document.querySelector('#id');
console.log(elem2);
var elem3 = document.querySelector('h3 span input');
console.log(elem3);
</script>
使用 querySelectorAll 用法和上面类似
<div class="box">abc</div>
<div id="id">def</div>
<script>
var elems = document.querySelectorAll('div');
console.log(elems);
</script>
button id="btn">点我一下</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
alert("hello world");
}
</script>
Element.innerText 属性表示一个节点及其后代的“渲染”文本内容
// 读操作
var renderedText = HTMLElement.innerText;
// 写操作
HTMLElement.innerText = string;
案例:
<div>
<span>hello world</span>
<span>hello world</span>
</div>
<script>
var div = document.querySelector('div');
// 读取 div 内部内容
console.log(div.innerText);
// 修改 div 内部内容, 界面上就会同步修改
div.innerText = 'hello js hello js';
</script>
Element.innerHTML 属性设置或获取HTML语法表示的元素的后代
// 读操作
var content = element.innerHTML;
// 写操作
element.innerHTML = htmlString;
案例:
<div>
<span>hello world</span>
<span>hello world</span>
</div>
<script>
var div = document.querySelector('div');
// 读取页面内容
console.log(div.innerHTML);
// 修改页面内容
div.innerHTML = 'hello js'
</script>
innerHTML 不光能获取到页面的 html 结构, 同时也能修改结构. 并且获取到的内容保留的空格和换行,所以innerHTML 用的场景比 innerText 更多
可以通过 Element 对象的属性来直接修改, 就能影响到页面显示效果
<img src="rose.jpg" alt="这是一朵花" title="玫瑰花">
<script>
var img = document.querySelector('img');
img.onclick = function () {
if (img.src.lastIndexOf('rose.jpg') !== -1) {
img.src = './rose2.png';
} else {
img.src = './rose.jpg';
}
}
</script>
//此时点击图片就可以切换图片显示状态
表单的以下属性都可以通过 DOM 来修改
<input type="button" value="播放">
<script>
var btn = document.querySelector('input');
btn.onclick = function () {
if (btn.value === '播放') {
btn.value = '暂停';
} else {
btn.value = '播放';
}
}
</script>
//假设这是个播放按钮, 在 "播放" - "暂停" 之间切换
CSS 中指定给元素的属性, 都可以通过 JS 来修改.
行内样式操作,适用于改的样式少的情况
element.style.[属性名] = [属性值];
element.style.cssText = [属性名+属性值];
案例:
<div style="font-size: 20px; font-weight: 700;">
哈哈
</div>
<script>
var div = document.querySelector('div');
div.onclick = function () {
var curFontSize = parseInt(this.style.fontSize);
curFontSize += 10;
this.style.fontSize = curFontSize + "px";
}
</script>
element.className = [CSS 类名];
修改元素的 CSS 类名. 适用于要修改的样式很多的情况
分成两个步骤
使用 createElement 方法来创建一个元素. options 参数暂不关注
var element = document.createElement(tagName[, options]);
案例:
<div class="container">
</div>
<script>
var div = document.createElement('div');
div.id = 'mydiv';
div.className = 'box';
div.innerHTML = 'hehe';
console.log(div);
var container = document.querySelector('.container');
container.appendChild(div);
var container = document.querySelector('.container');
container.insertBefore(newDiv, container.children[0]);
</script>
使用 appendChild 将节点插入到指定节点的最后一个孩子之后
使用 insertBefore 将节点插入到指定节点之前
使用 removeChild 删除子节点
oldChild = element.removeChild(child);
实现提交功能
// 给点击按钮注册点击事件
var submit = document.querySelector('.submit');
submit.onclick = function () {
// 1. 获取到编辑框内容
var edits = document.querySelectorAll('.edit');
var from = edits[0].value;
var to = edits[1].value;
var message = edits[2].value;
console.log(from + "," + to + "," + message);
if (from == '' || to == '' || message == '') {
return;
}
// 2. 构造 html 元素
var row = document.createElement('div');
row.className = 'row';
row.innerHTML = from + '对' + to + '说: ' + message;
// 3. 把构造好的元素添加进去
var container = document.querySelector('.container');
container.appendChild(row);
// 4. 同时清理之前输入框的内容
for (var i = 0; i < 3; i++) {
edits[i].value = '';
}
}