文章目录
原型链关键字总结
原型对象:prototype
函数的属性,指向一个对象,这个对象是通过该函数作为构造函数创建的所有实例的原型
修改原型会影响所有已创建的实例,但重写整个原型对象不会影响已创建的实例。
如下
重写了整个原型对象,但依旧输出1,只有新建的才输出2
个人理解是
new调用构造函数时,会给实例的__ proto__,(也就是函数的prototype),赋予函数的prototype值,也就是浅拷贝,二者指向同一对象,而再次新建时修改了原指针,指向了新的原型对象,但旧实例,还是有原对象的索引
js
function Foo() {}
const foo1 = new Foo();
const foo2 = new Foo();
Foo.prototype.value = 1;
console.log(foo1.value);
console.log(foo2.value);
Foo.prototype = { value: 2 };
const foo3 = new Foo();
console.log(foo1.value);
console.log(foo2.value);
console.log(foo3.value);
//1 1 1 1 2
对象原型:__ proto__
对象的属性:指向该对象的构造函数的原型(对象)
js
console.log(man.prototype);//man是函数,manba是其实例
console.log(manba.__proto__);
//{ name: '', age: '' }
//{ name: '', age: '' }
new` 关键字会创建一个新的空对象,并将该对象的 `__proto__` 设置为 `man.prototy
javascript
function People(name){
this.name=name
}
//people方法
People.prototype.Hello=function(){
return `Hello ${this.name}`
}
function Student(name,score){
People.call(this,name)
this.score=score
}
//将student的原型指向Person的原型,继承了person的方法
//未指定原型实例无法访问父类方法
Student.prototype=Object.create(People.prototype)
//指定原型后constructor会指向父类构造函数,修复
Student.prototype.constructor=Student
//
let xiaoming= new Student('xiaoming','80')
console.log(xiaoming);
console.log(xiaoming.constructor);
console.log(xiaoming.Hello());
create
javascript
Object.create(People.prototype);
//创建一个新People.prototype对象,它的原型指向People.prototype
class实现
js
class People{
constructor(name){
this.name=name
}
Hello(){
return `Hello ${this.name}`
}
}
//继承
class Student extends People{
constructor(name,score){
super(name)
this.score=score
}
printScore(){
return `score : ${this.score}`
}
}
let p1=new People('xiaoF')
let stu=new Student('xiaoming','100')
console.log(stu.printScore());
console.log(stu.Hello());
console.log(p1.Hello());
//console.log(p1.printScore());(无)
面向对象编程
封装
-
私有属性
_约定,#真语
同样有静态属性和方法
jsclass Person { constructor(name, age) { this._name = name; // 使用下划线表示私有属性 this._age = age; } }
-
私有方法
jsclass animal{ #name; constructor(name){ this.#name=name this.#firstPrint() } getName(){ return this.#name } #firstPrint(){ console.log(this.#name); } firstPrint(){ console.log(this.#name); } } let dog =new animal('dog') dog.firstPrint()
带#与不带#可以同时存在,为俩种不同的方法
还可以组合私有静态
js
class Cat extends Animal{
static #count=0
constructor(name){
super()
this.name=name;
(Cat.#count)++
}
static getNum(){
return Cat.#count
}
}
let cat1=new Cat('mm')
console.log( Cat.getNum());
抽象
没有java类似的抽象类关键字
只能通过throw error来模拟抽象类
new.target
不仅可以在类的构造函数中使用,还可以在任何函数中使用。它是一个特殊的元属性,用于检测当前函数是否通过new
关键字被调用,以及调用时的构造函数是什么。
js
// 模拟抽象类
class Shape {
constructor() {
if (new.target === Shape) {
throw new Error("Cannot instantiate abstract class");
}
}
// 抽象方法
area() {
throw new Error("Abstract method must be implemented");
}
}
多态
实现多态发生原型链的分支
js
class Cat extends Animal{
static #count=0
constructor(name){
super()
this.name=name;
(Cat.#count)++
}
static getNum(){
return Cat.#count
}
Print(){
console.log( `cat: ${this.name}`);
}
}
class dog extends Animal{
static #count=0
constructor(name){
super()
this.name=name;
(dog.#count)++
}
static getNum(){
return dog.#count
}
Print(){
console.log(`dog: ${this.name}`);
}
}
总结
并未含有java类似的关键字(abstract)严格声明,而是通过抛出错误等来进行限制
异步编程
基础循环
遵循同步任务->微任务->宏任务
清空微任务队列后,才会进入下一次宏任务,如此循环
微任务
由js自身发起的,如promise
宏任务
由浏览器发起,如settimeout
javascript
setTimeout(() => {
// 宏任务
console.log('setTimeout');
}, 0);
new Promise((resolve, reject) => {
resolve();
console.log('promise1'); // 同步任务
}).then((res) => {
// 微任务
console.log('promise then');
});
console.log('同步任务'); // 同步任务
解析
- 第一个宏任务setTimeout暂存,
- 执行promise的构造函数(同步任务)//修改promise的状态,触发then的微任务暂存并输出promise1
- 执行最终的log输出同步任务
- 微任务队列不为空,执行输出promise then
- 执行最终宏任务 输出setTimeout
输出顺序
javascript
promise1
同步任务
promise then
setTimeout
宏任务嵌套微任务
javascript
new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
console.log('setTimeout'); // 宏任务
}, 0);
console.log('promise1');
}).then((res) => {
// 微任务
console.log('promise then');
});
console.log('同步任务');
- 暂存promise构造函数中的宏任务并输出promise1
- 由于promise的状态在宏任务中改变,故then还未触发,输出最后的同步任务
- 此时 微任务未空,执行暂存的宏任务, resolve();触发微任务,并输出同步任务promise1'
- 执行then输出promise then