Files
rikako-note/javascript/js.md
2022-06-23 00:13:20 +08:00

203 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# JavaScript基础
- ## js特性
- js是一门动态语言包含类型、运算符、标准内置对象和方法
- js支持函数是编程
- js通过原型链来实现面向对象编程
- ## js类型
- js中包括如下类型
- Number数字
- String字符串
- Boolean布尔
- Function函数
- Object对象
- Symbol符号
- 其他类型:
- undefined
- null
- Array
- Date
- RegExp
- ## js变量的声明
- js可通过如下关键字来声明变量
- let
- 块级作用域内有效,只能在声明该变量的块中使用
- 在let声明变量之后变量只能在声明之后被使用
- const
- 声明一个不可变的变量,该变量在定义域中总是可见的
- const变量也只能在块定义域中被使用在声明块之外无法访问
- var
- 通过var关键字声明变量之后变量在整个函数的范围内都是可见的
- 在定义var变量的方法之外均无法访问var变量
- 但是在声明var变量的方法中即使在声明var变量的语句之前也可以使用var变量变量值为undefined
- js变量作用域特性
- 在js语言中原本是没有块作用域的变量只有函数范围的作用域。但是通过引入const和let关键字js支持声明块作用域的变量。
- ## js运算符
- ==运算符和===运算符
- ==运算符具有类型自适应的功能
```java
# 对于==运算符,如果运算符两边的类型不一致的话,
# 会尝试进行类型转换并比较
123==“123” true
1==true true
```
- ===相对于==,比较前并不会进行强制类型转换
```java
1===1 false
1===true false
```
- 相对应的,对于比较不相等的操作,也存在!=和!==操作,其区别类似于==和===的区别
- ## js流程控制
- js中for循环可以分为如下两种
- for in循环
- 对于for in循环会遍历索引项对数组来说是序号对map来说是keyset为空
- for of循环
- 对于for of循环会遍历值value而不是键key
- js中的switch流
- 相比于c中的switch只支持数字js中的switch既支持数字又支持字符串switch和case之间是通过===运算符来判断是否严格相等的
- ## js对象
- js对象类似与map结构由key和value组成的键值对构成
- js对象的创建有如下两种方式
- 字面量创建
```javascript
let obj={
name:"touma",
id:"A001",
husband:{
name:"haruki",
id:"A002"
}
}
```
- 通过对象原型来创建对象
```javascript
function Person(name,id) {
this.name=name
this.id=id
}
let person=new Person("touma","A001")
```
- 访问对象元素的方式
```javascript
let person={
name:"touma",
id:"A001"
}
// 通过.来访问
cosnole.log(person.name)
// 通过[]来访问
console.log(person["name"])
```
- ## js数组
- js中允许通过下标在超过当前数组长度的位置插入元素其中中间未插入元素的部分元素值均为undefined
```javascript
let arr=[1,2];
arr[100]=101;
// 其中下标位于299之间的元素均为undefined数组长度为101
```
- js中数组可以通过forEach方法对数组中每个值执行调用
```javascript
let arr=[1,2];
// 将数组中的每个元素平方
arr.forEach((value,index,arr)=>{
arr[index]=value*value;
});
```
- ## js中的函数
- 函数在调用结束之后都会返回一个值如果函数在结束时没有return语句或是return语句后没有跟随值都会返回一个undefined
- 在js函数中可以通过展开运算符...来接受任意个数的参数,并且,对于数组,...也可以将其展开为被逗号分隔的参数列表
```javascript
let arr = [1, 2, 3];
function sum(...arr) {
let result = 0;
for (let ele of arr) {
result+=ele;
}
return result;
}
console.log(sum(...arr));
```
- ## js中的嵌套函数
- 如果在js中一个函数依赖与其他函数但是依赖的其他函数并不会在其他地方被使用那么可以将依赖的函数放在函数内部
```javascript
function outer_func() {
function inner_func() {
// 除了被outer_func调用外不会在其他地方被调用
}
}
```
- 通过嵌套函数,可以有效的减少全局作用域中的函数名称,可以防止污染全局作用域的命名
- ## js中的闭包
- 每当js中调用一次函数时都会创建一个作用域对象用来保存在函数中创建的局部变量。
- 当返回值为函数时,返回的函数中将会指向先前被创建的作用域对象,这样作用域对象在函数结束后就不会被回收
- 由于闭包可以保存状态,并且对外部隐藏状态,故而闭包可以代替对象来使用。闭包通过向外部返回一个操作内部局部变量的函数,保证位于内部的局部变量只能通过返回的函数来访问,保证了变量的安全
- ## js继承和原型链
- 和面向对象的编程语言不同js的继承是通过原型来实现的。每个对象都有一个原型对象以原型为模板从原型中继承方法和属性。原型对象也拥有原型一层一层以此类推构成了原型链。
- 每一个对象都有内置的属性其中可以通过内置的__proto__属性来访问一个对象的prototype对象
- 原型链中属性的查找规则:
- 如果在一个对象中想要查找的属性不存在那么将会在当前对象的prototype对象中查找属性
- 如果prototype对象中属性仍然找不到那么就在prototype对象的prototype对象中查找属性
- 一直向前回溯,直到属性被找到或者回溯到原型链尾部
- 原型链结构:
- 对于所有的对象默认__proto__指向的原型对象都是Object.prototype
- Obejct.prototype是位于原型链尾端的对象Object.prototype的原型对象是null
- 为对象指定原型对象:
- 通过Object.create函数指定原型对象,该方法会创建一个新对象并为其指明原型对象
```javascript
let proto_obj={
name: "kazusa",
greeting() {
console.log("hello, "+this.name);
}
};
let child_obj=Object.create(proto_obj);
child_obj.greeting();
```
- 通过构造函数
- 在js中所有函数都有一个prototype属性当该函数被作为构造函数调用时构造函数创建的所有新对象的__proto__属性都会被设置为该函数的prototype属性
- 在将构造函数的protype属性设置为制定的对象后prototype对象中内置属性constructor发生了变化需要重新将原型对象的constructor制定为构造函数
- ## 在js中实现类的继承
- js中有如下关键字可以简化类的继承其底层仍然使用原型链来实现类的继承关系
- class用于类的声明
- extends用于类的继承
- constructor用于声明构造函数
- super():调用父类构造函数来实现子类构造函数
- js中可以通过#字符来将变量或者方法标明为类私有的
- js中继承实现
```javascript
class People {
#name
constructor(name) {
this.#name = name
}
greeting() {
console.log("hello, i am " + this.#name)
}
}
class Student extends People {
#grade
constructor(name, grade) {
super(name)
this.#grade = grade
}
greeting() {
console.log("hi, fucking bitch, miss your dad?")
}
}
let p=new Student("touma",6)
console.log(Object.getPrototypeOf(p))
```
- js通过原型链实现继承的细节
- js可以首先为父类创建构造函数
- js在子类的构造函数中可以先调用ParentConstructor.callthis,args)方法来对子类的对象添加父类的成员变量
- 在完成子类对象成员变量的赋值后可以通过Object.create创建一个以ParentConstructor.prototype为__proto__的新对象并且将ChildConstructor.prototype设置为新对象
- 最后将新对象的constructor属性设置为ChildConstructor