专栏简介: 前端从入门到进阶
************题目来源: leetcode,牛客,剑指offer.
创作目标: 记录学习JavaEE学习历程
希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长.
学历代表过去,能力代表现在,学习能力代表未来!
目录
1. 初始 JavaScript
1.1 JavaScript 是什么?
JavaScript 简称 JS
- 是世界上最流行的编程语言之一
- 是一个脚本语言, 通过解释器运行
- 主要在客户端(浏览器) 上运行, 也可以基于 node.js 在服务器端运行.
1.2 JavaScript 能做的事情
- 网页开发(更复杂的特效和用户交互)
- 网页游戏开发
- 服务器开发(node.js)
- 桌面程序开发(Electron, VSCode 就是这么来的)
1.3 JavaScript 和 HTML 和 CSS 的关系
- HTML: 是网页的结构
- CSS: 网页的表皮
- JavaScript: 网页的行为(魂)
1.4 JavaScript 运行过程
- JS 编写的代码保存在文件中, 也就是储存在硬盘上.
- 双击 .html 文件, 浏览器就会读取文件 , 把文件内容加载到内存中(数据流向:硬盘->内存)
- 浏览器会解析用户编写的代码 , 把代码翻译成二进制的 , 能让计算机识别的指令(解释器的工作)
- 得到的二进制指令会被 CPU 加载并执行.(数据流向: 内存->CPU)
浏览器分为 渲染引擎 和 JS引擎
- 渲染引擎: 解析 HTML+CSS , 俗称"内核"
- JS 引擎: 也就是解释器. 典型的就是 Chrome 内核中的V8
Tips: JS 引擎 会逐行读取 JS 代码内容 , 然后解析成二进制指令, 再执行.
1.5 JavaScript 的组成
- ECMAScripe(简称 ES): JavaScript 语法.
- DOM: 页面文档对象模型, 对页面中的元素进行操作.
- BOM: 浏览器对象模型, 对浏览器窗口进行操作.
仅有 JS 语法, 只能写一些基础的逻辑流程, 但要想完成更复杂的任务, 完成和浏览器以及页面的交互, 那么就需要 DOM API 和 BOM API.
ESCMAScript 是一套"标准", 无论是啥样的 JS 引擎都需要遵守这个标准来实现.
2. 前置知识
第一个程序
<script>
alert("你好!")
</script>
- JavaScript 代码可以嵌入到 HTML 的 script 标签中
2.1 JavaScript 的书写形式
1) 行内式
直接嵌入到 html 元素内部
<input type="button" value="点我一下" onclick="alert('hello')">
2) 内嵌式
写到 script 标签中
<script>
alert("你好!")
</script>
3) 外部式
写到单独的 .js 文件中
alert("hello");
<script src="script.js"></script>
Tips: 这种情况下 script 标签内部不能写代码 , 必须空着.
2.2 输入输出
输入: prompt
弹出一个输入框
//弹出一个输入框
prompt('请输入您的姓名:>')
输出: alert
弹出一个警示对话框, 输出结果
//弹出一个输出框
alert("hello")
输出: console.log
在控制台打印一个日志
//向控制台输出日志
console.log('这时一条日志')
需要打开浏览器的开发者工具(F12)=>Console 标签页, 才能看到结果
**Tips: **
- console 是 js 中的一个"对象"
- . 表示获取对象中的某个属性或方法, 可直观理解为"的"
- console.log 就可以理解成, 使用"控制台" 对象的"log" 方法
3. 语法概览
3.1 变量的使用
基本用法
创建变量(变量定义/变量声明/变量初始化)
var name = 'zhangsan'
var age = 20;
var 是 JS 中的一个关键字, 表示这是一个变量.
代码示例:
弹框提示用户输入信息, 再弹框显示
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");
** Tips:**
- 表示字符串拼接, 也就是将两个字符串首尾拼接成一个字符串
- \n 表示换行
var 与 let 的区别:
var 定义变量属于老式写法, let 定义变量属于新式写法, let 的语法规范更符合我们常用的主流语言, 类似于一个变量不能重复定义, 变量的作用域限制等...
var a = 10;
var a = 10;
// let则不允许这种写法
{
var a = 10
}
console.log(a);
//let不允许这种写法
3.2 理解 动态类型
- JS 的变量类型是程序运行过程中才能确定的(运行到 = 语句才会确定类型)
var a = 10;//数字
var name = '张三'//字符串
- 随着程序的运行, 变量的类型还可能发生变化.
var a = 10;//数字
a = '张三'//字符串
这一点和 C++ Java...这类静态语言差异较大. 静态语言中, 一个变量在创建时类型就确定了, 不能在程序运行时改变, 如果尝试改变直接编译报错.
3.3 基本数据类型
JS 中内置的几种类型
- number: 数字.(不区分整数和小数)
- boolean: true真, false假
- string: 字符串类型
- undefined: 表示未定义的值
- null: 表示空值
Tips: undefined 和 null 都表示取值非法的情况 , 不过侧重点不同.
- null 表示当前值为空 , 有一个空盒子.
- undefined 表示当前变量未定义 , 连一个空盒子都没有.
3.4 JS 中的数组
let arr = [];
let arr1 = [1,2,3,4,5]
let arr2 = [1,true,'hello',[]]
JS 中, 数组的元素类型不要求统一, 可以是任意类型, 实际上动态语言都是如此.
操作数组元素: 访问下标
let arr = [1,true,'hello',[]]
console.log(arr[0])
console.log(arr[1])
console.log(arr[2])
当我们操作主键发现, 将负数或字符串作为下标, 也能正常运行, 那么就可以得出 JS 的数组并不是一个传统意义上的只能按下标来取元素的数组, 而是一个带有键值对性质的东西
let arr = [1,true,'hello']
arr[-1] = 'world'
arr['我是下标:'] = "haha"
console.log(arr)
JS 中数组的遍历:
let arr = ['张三','李四', '王五', '赵六']
for(let i = 0;i < arr.length;i++){
console.log(arr[i]);
}
for(let i in arr){
//此处 i 是数组下标
console.log(arr[i]);
}
for(let elem of arr){
//elem是数组中元素
console.log(elem);
}
给数组添加元素:
- 通过修改 length 新增.
通过在末尾新增元素 , 新增元素是 undefined.
<script>
let a = [1,2,3,4,5];
a.length = 15;
console.log(a);
</script>
- 通过下标新增
如果下标超过元素赋值范围 , 则会给指定位置插入新元素.
<script>
let a = [];
a[3] = 10;
console.log(a);
</script>
之前空余位置为 undefined.
- 使用 push 进行追加元素
代码示例: 给定一个数组 , 把数组中的偶数放入newArray中.
<script>
let a = [1, 2, 3, 4, 5, 6, 7,8 ,9 ,10];
let newArray = [];
for(let elem of a){
if((elem & 1) == 0){
newArray.push(elem);
}
}
console.log(newArray);
</script>
删除数组中的元素:
splice(startIndex, count, 变长参数);
如果只有前两个参数没有变长参数那么就是删除
let arr = ['张三','李四', '王五', '赵六']
arr.splice(2,1);//相当于删除王五
console.log(arr)
如果三个参数都有, count = 1, 相当于替换元素
let arr = ['张三','李四', '王五', '赵六']
arr.splice(2,1,'haha');//相当于将王五替换
console.log(arr)
如果三个元素都有, count = 0, 相当于添加元素
let arr = ['张三','李四', '王五', '赵六']
arr.splice(2,0,'haha');//相当于将王五替换
console.log(arr)
所以 splice 操作非常灵活, 可以同时做到, 删除, 添加, 修改元素.
3.5 函数
语法格式:
//创建函数/函数声明/函数定义
function 函数名 (形参列表){ //不必写形参类型
函数体
return 返回值//不必写返回值类型
}
//函数调用
函数名(实参列表) //不考虑返回值
返回值 = 函数名(实参列表) // 考虑返回值
**代码示例: **
function hello(){
console.log('hello')
}
hello();
function add(x, y){
return x + y;
}
console.log(add(1, 3));
对应 JS 这类动态语言, 不需要''重载''这样的概念, 只需通过一个特殊变量 argument, 就可以拿到所有实参.
function add(){
let result = 0;
for(let elem of arguments){
result += elem;
}
return result;
}
console.log(add(1, 2));
console.log(add(1, 2, 3));
console.log(add(1, 2, 3, 4));
3.6 函数表达式:
let add = function (){
let result = 0;
for(let elem of arguments){
result += elem;
}
return result;
}
console.log(add(1, 2));
console.log(add(1, 2, 3));
console.log(add(1, 2, 3, 4));
console.log(typeof(add))
此时形如 function(){ } 这样的写法定义了一个匿名函数, 然后将这个匿名函数用一个变量来表示, 后面就可以通过这个 add 变量来调用函数了.
JS 中函数是一等公民, 可以用变量来保存, 也可以作为其他函数的参数或返回值.
3.7 作用域:
某个标识符在代码中的有效范围, 在 ES6 标准之前, 作用域主要分为两个:
- 全局作用域: 在整个 script 标签中, 或者单独的 js 文件中生效.
- 局部作用域/函数作用域: 在函数内部生效.
//全局变量
let num = 10;
console.log(num);
function test(){
//局部变量
let num = 20;
console.log(num);
}
3.8 作用域链:
背景:
- 函数可以定义在函数内部.
- 内层函数可以访问外层函数的局部变量.
内部函数可以访问外部函数的变量, 采用的是链式查找的方式. 从内到外依次进行查找.
let num = 1;
function test1(){
let num = 10;
function test2(){
let num = 20;
console.log(num);
}
test2();
}
test1();
//执行结果
20
执行 console.log(num)时, 会先在 test2 的作用域中查找 num, 如果没有找到, 则继续去 test1 中查找. 如果还没有找到, 就去全局作用域中查找.
4. 对象
基本概念:
对象指的是一个具体的事物.
在 JS 中, 字符串, 数值, 数组, 函数都是对象
每个对象中包含若干的属性和方法:
- 属性: 事物的特征.
- 方法: 事物的行为.
eg: 你有一个朋友.
她的身高, 体重, 三围这些都是属性.
她的唱, 跳, rap 都是方法.
JavaScript 的对象和 Java 的对象概念上基本一致, 只是具体的语法表达形式差别较大.
4.1 使用 字面量 创建对象[常用]
使用 {} 创建对象.
let a = {};//创建一个空的对象
let student = {
name:'张三',
height:175,
weight:170,
sayhello: function(){
console.log('hello everyone');
}
};
- 使用 {} 创建对象.
- 属性和方法使用键值对的方式来组织.
- 键值对之间使用 , 分割. 最后一个属性后面的 , 可有可无.
- 键和值之间使用 : 分割.
- 方法的值是一个匿名函数.
使用对象的方法和属性:
// 1. 使用 . 成员访问运算符来访问属性 '.' 可以理解为"的"
console.log(student.name);
// 2. 使用 [] 访问属性, 此时属性需要加上引号
console.log(student['height']);
// 3. 调用方法
student.sayhello();
4.2 使用 new Object 创建对象
let student = new Object();//和创建数组类似
student.name = '张三';
student.height = 175;
student['weight'] = 170;
student.sayHello = function(){
console.log('hello');
}
Tips: 使用 {} 创建的对象也可以使用 student.name = '张三', 这样的方式来新增属性.
4.3 使用构造函数创建对象
之前创建对象的方式只能创建一个对象, 而使用构造函数可以很方便的创建多个对象.
基本语法:
function 构造函数名 (形参){
this.属性 = 值;
this.方法 = function..
}
let obj = new 构造函数名(实参);
Tips:
- 在构造函数内部使用 this 关键字来表示当前正在构建的对象.(this 相当于"我")
- 构造函数无需 return.
- 创建对象时必须使用 new 关键字.
代码示例:
使用构造函数创建 猫咪 对象
使用构造函数可以把相同的属性和方法创建提取出来, 简化开发过程.
function Cat(name, type, sound){
this.name = name;
this.type = type;
this.miao = function(){
console.log(sound);
}
}
let buo = new Cat('咪咪', '布偶猫', '哈海害');
let gudu = new Cat('咕嘟', '中华田园猫', '喵呜');
let ciqiu = new Cat('刺球', '金渐层', '咕噜噜');
4.4 理解 new 关键字
new 关键字的执行过程:
- 先在内存中创建一个空的对象.
- this 指向刚才的空对象(将上一步的对象作为 this 的上下文)
- 执行构造函数的代码, 给对象创建属性和方法.
- 返回这个对象(构造函数本身不需要 return, 由 new 代劳了)
4.5 JavaScript对象和Java对象的区别
1) JavaScript 没有''类''的概念
对象本质上就是"属性" + "方法"
类相当于把一些具有共性的对象的属性和方法单独提取出来, 本质上是用户自定义的类型.
在 JavaScript 中的"构造函数"也能起到类似的效果.
即使不使用 构造函数 , 也可以通过 {} 的方式指定出一些对象.
2) JavaScript 对象不区分 "属性" 和 "方法"
JavaScript 中函数是"一等公民", 和普通变量一样, 存储了函数的变量能够通过() ;来进行调用执行.
3) JavaScript 对象没有访问控制机制, 对象中的属性可以随意被外界访问.
4) JavaScript 对象没有"继承"
继承本质上就是 "让两个对象建立关联", 或者说让一个对象能够重用另一个对象的属性/方法.
JavaScript 中使用 "原型" 机制实现类似的效果.
例如: 创建一个 cat 对象和 dog 对象, 让这两个对象都能使用 animal对象中的 eat 方法.
通过 proto 属性来建立这种关联关系(proto 翻译作: "原型")
let dog = {
name: 'dog',
_proto_: animal
};
let cat = {
name:'cat',
_proto_:animal
};
dog.eat();
cat.eat();
当 eat 方法被调用时, 先在自己的方法列表中寻找, 如果找不到就去原型的方法中找, 如果还找不到就去原型的原型中找....最后在 Object 中还找不到, 那就是未定义.
5) JavaScript 没有"多态"
多态的本质在于 程序员 不必关注具体的类型, 就能使用其中某个方法.
C++/Java 等静态类型的语言对应类型的约束和效验比较严格. 因此通过子类继承父类, 并重写父类的方法的方式来实现多态的效果.
但 JavaScript 中本身就支持动态类型, 程序员在使用某个方法时, 也不需要对对象的类型作出明确区分, 因此无需再语法层面上支持多态.
function add(list ,s){
list.add(s);
}
add 对 list 这个参数本身就没有任何限制, 只需要 list 这个对象有 add 方法即可. 不必像 Java 那样先继承再重写.
版权归原作者 Node_Hao 所有, 如有侵权,请联系我们删除。