这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。
1.为什么要有原型?
function Student(name,age){
this.name=name;
this.age=age;
this.commonTeacher=["李四","张三","王二麻子"];
this.showName=function(){
console.log("我的名字是",this.name)
}
this.showCommonTeacher=function(){
console.log("我的老师有",this.commonTeacher)
}
}
const student1=new Student("学生1",18)
const student2=new Student("学生2",19)
student1.showCommonTeacher();//我的老师有 [ '李四', '张三', '王二麻子' ]
student2.showCommonTeacher()//我的老师有 [ '李四', '张三', '王二麻子' ]
可以看出通过构造函数(使用了new的函数就是构造函数)创建的实例,他们的公共属性commonTeacher是完全一样的属性,分开创建实例的话,会开辟两个堆空间,那么使用原型的话,可以使用同样的堆地址赋值不同的实例,通过堆地址寻址找到同一个堆空间(commonTeacher)
2.如何使用原型?
原型上的方法和属性都可以被构造函数的实例所共享。原型可以理解为是一个共用对象,被现有对象所继承了
function Student(name,age){
this.name=name;
this.age=age;
this.showName=function(){
console.log("我的名字是",this.name)
}
}
Student.prototype.commonTeacher=["李四","张三","王二麻子"];
Student.prototype.showCommonTeacher=function(){
console.log("我的老师有",this.commonTeacher)
}
const student1=new Student("学生1",18)
const student2=new Student("学生2",19)
student1.showCommonTeacher();//我的老师有 [ '李四', '张三', '王二麻子' ]
student2.showCommonTeacher();//我的老师有 [ '李四', '张三', '王二麻子' ]
每创建一个实例就会默认给他添加一个__proto__属性,这个属性装了一个堆地址,指向构造函数的原型对象
那也就是说Student.prototype===student1.__ proto__===student2.__ proto__
经典例子1表现堆地址的考题
解释:地址的转移,并不是空间内容的覆盖,相当于obj变量的地址分给objnew变量,现在objnew指向obj的堆地址,实际堆内容为{username:'u',age:20}。后面obj变量又被赋与了一个新的对象堆地址,内容为{username:'a',age:18}。
let obj={username:'u',age:20};
const objnew=obj;
obj={username:'a',age:18};
console.log("obj",obj);//{username:'a',age:18}
console.log("objnew",objnew);//{username:'u',age:20}
经典例子2 原型对象的覆盖
function F(a,b,c){ this.a=a; this.b=b; this.c=c }
F.prototype.common=[1,2,3,4];
F.prototype.common.push(5)
const f=new F(1,2,3);
F.prototype={a:"a",b:"b"};
console.log(f.common)//[ 1, 2, 3, 4, 5 ]
解释:实例化在前,先创建的实例对象f,里面有一个__proto__指向目前F.prototype地址指向的堆空间,这个时候F.prototype地址变量被替换成新地址了,也就是指向变了,那么原来的f.__ proto__指向的空间不会被垃圾回收掉,因为实例化有变量指向了它。
3.ES6类
写在一个类上的属性一定要设计为和类强关联的,给对象赋值的方法,属性(public)或者方法,构造器
在类中一共做了三件事
第一件事:在堆中为类的实例分配一个内存空间
第二件事:调用对应的构造函数【构造器】。会自动匹配几个参数的构造器,否则报错提示(有重载除外)
第三件事:把对象赋值给对象变量
"use strict";
class Person {
constructor(name, age) {
this.name = "name";
this.age = 23;
this.strArray = ["12", "23"];
this.strArray2 = [1, "2"];
this.f = () => { };
this.name = name;
}
doEat(a, b) {
console.log("a", "b", a, b);
}
}
const p = new Person("神说要有光_zy", 23);
let a = { username: "神说要有光_zy2", age: 321 };
4.TS类
由3中Es6中类可以延伸出来TS的类,主要是在Es6上面做了属性修饰,类型控制,借鉴了java的很多强类型的特性过来,这样极大的丰富了类。可以是开发者在开发的时候规避很多错误
class Person {
private name: string = "name";
public age: number = 23;
public strArray: string[] = ["12", "23"];
public strArray2: Array<string | number> = [1, "2"];
public f: () => void = () => {};
public doEat(a: string, b: string): void {
console.log("a", "b", a, b);
}
constructor(name: string, age: number) {
this.name = name;
}
}
const p = new Person("神说要有光_zy", 23);
let a = { username: "神说要有光_zy2", age: 321 };
5.配置TS和ES6和ES5同代码的对比环境
5.1 使用pracel打包工具
pracel打包工具配置相比于webpack及其简单
1.全局安装
> npm install -g parcel-bundler
2.新建一个index.html,引入一个index.ts文件
3.配置npm script工作流命令"build": "parcel ./index.html"
4.运行npm run build就成功进行打包,并且index.html打包后直接加载的js文件,可以进行网页调试
5.2 配置Ts环境
1.使用tsc --init配置基本的Ts环境目录,生成tsconfig
2.关注rootDir(输入目录),outDir(输出目录),target:'es6',等等都可以更改打包后的代码相对比,在ts.config同级目录下进行tsc,会根据ts.config自动将输入目录中打包成js文件
3.使用nodemon监听,ts-node配置dev环境,下面这命令的意思是监听src下面的改变,就是用ts-node执行index.ts
"nodemon --watch src/ -e ts --exec ts-node src/index.ts"