daily commit
This commit is contained in:
171
javascript/js.md
171
javascript/js.md
@@ -31,4 +31,173 @@
|
|||||||
- 但是在声明var变量的方法中,即使在声明var变量的语句之前,也可以使用var变量,变量值为undefined
|
- 但是在声明var变量的方法中,即使在声明var变量的语句之前,也可以使用var变量,变量值为undefined
|
||||||
- js变量作用域特性:
|
- js变量作用域特性:
|
||||||
- 在js语言中,原本是没有块作用域的,变量只有函数范围的作用域。但是,通过引入const和let关键字,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来说是key,set为空)
|
||||||
|
- 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;
|
||||||
|
// 其中,下标位于2~99之间的元素均为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.call(this,args)方法来对子类的对象添加父类的成员变量
|
||||||
|
- 在完成子类对象成员变量的赋值后,可以通过Object.create创建一个以ParentConstructor.prototype为__proto__的新对象,并且将ChildConstructor.prototype设置为新对象
|
||||||
|
- 最后,将新对象的constructor属性设置为ChildConstructor
|
||||||
Reference in New Issue
Block a user