JS构造函数
2021-06-03 03:02
标签:color 工厂 保存 注意 san 多少 tor als 实例化 JS构造函数 标签:color 工厂 保存 注意 san 多少 tor als 实例化 原文地址:https://www.cnblogs.com/Afanadmin/p/12355437.html构造函数
{
/*
工厂函数通过new运算符改造成了 构造函数;
构造函数:
1.首字母大写; 为了让普通函数和构造函数的区分
2.this指向实例化对象
*/
function Person(name,age){
this.num = 0;
this.name = name;
this.age = age;
this.hobby = function(){
console.log("喜欢篮球");
};
}
// 调用构造函数:
// new : 实例化;
let zhangsan = new Person("张三",20);
{
// 静态属性和方法;(属于类本身) -> 静态成员
// 假如需要统计一下这个构造函数有多少个实例化对象:
let zhangsan = new Person("张三",20);
// zhangsan.num ++;
// console.log(zhangsan.num);//1
let lisi = new Person("李四",21);
// lisi.num ++;
// console.log(lisi.num);//1
// 可以看到上面有两个实例化对象了,但结果依然还是1;
// 所以这个属性就要放到构造函数中当属性;
Person.num = 0;
Person.fn = function (){
console.log("fn");
};
Person.num ++;
Person.num ++;
console.log(Person.num);//2
}
}
构造函数性能问题
{
// 构造函数性能
function Person(name){
this.name = name;
this.age = 20;
this.hobby = function(){
console.log("喜欢篮球")
}
}
let zhangsan = new Person("张三");
let lisi = new Person("李四");
console.log(lisi.hobby === zhangsan.hobby);//false -> 对象的比较:不仅要值一样,地址也需要一样
// 在这里可以看到有两个实例化对象,他们在内存里分别保存了同样的内容,占据了一些内存;
}
原型
{
// 原型
function Person(name){
this.name = name;
this.age = 20;
// this.hobby = function(){
// console.log("喜欢篮球")
// }
}
let zhangsan = new Person("张三");
let lisi = new Person("李四");
// 什么是原型呢:每一个构造函数,在实例化的过程中,它都会有两个部分构成:1.构造函数(本身);2.公共空间(原型);
Person.prototype.hobby = function(){//方法可以放到原型上面
console.log("喜欢篮球");
}
console.log(lisi.hobby === zhangsan.hobby);//true -> 方法放到原型上面之后,不管是实例化多少个对象,他们的方法都是同一个方法,而不是在内存里面新开辟的地址,所以这样就更节约性能
// 原型:1.this指向还是实例化对象 2.每一次声明构造函数的时候prototype都是自动有的
/*
构造函数有两部分:1.本身;2.原型
实例化对象也是有两部分:1.自身属性和方法(也就是构造函数里面的属性和方法); 2.自己的原型(__proto__)
*/
console.log(zhangsan.__proto__ === Person.prototype);//他们两个是同样一个东西,只是表示形式不一样而已~
// 原型的固有属性;
console.log(Person.prototype.constructor === Person);//指向构造函数
console.log(zhangsan.constructor === Person);//true -> 可以用来判断实例化对象是哪个构造函数
// 原型prototype注意点:
// 可以追加方法,不要进行覆盖,即使覆盖了,也要把constructor指向构造函数;
Person.prototype = {
hobby(){
console.log("喜欢篮球")
},
constructor:Person
}
// prototype的constructor的情况:可以判断是否是 数组,对象等系统对象;
let arr = [1,2,3];
console.log(arr.constructor === Array);//true
let str = "123324";
console.log(str.constructor === String);//true
}
构造函数,原型,实例化 三者关系:
// 构造函数,原型,实例化 三者关系:
let temp;
let temp1;
function Person(name){
this.name = name;
this.age = 20;
temp = this;
}
Person.prototype.fn = function(){//原型可以加方法
console.log("fn");
temp1 = this;
}
let zhangsan = new Person("张三");//构造函数可以通过new得到对象
// 这时候: 实例化对象的属性和方法来自构造函数的属性和方法;
console.log(zhangsan);
// this指向实例化:
console.log(zhangsan === temp);//true
// prototype 指向实例化对象
zhangsan.fn();
console.log(zhangsan === temp1);//true
// constructor指向构造函数
console.log(Person.prototype.constructor === Person);//true
工厂函数与构造函数的对比:
{
// 工厂函数与构造函数的对比:
{
function Person(name){
let obj = {};
obj.name = name;
obj.age = 20;
obj.fu = function(){
console.log("fn");
}
return obj;
}
let zhangsan = Person("张三");
}
{
function Person(name){
this.name = name;
this.age = 20;
}
Person.prototype.fn = function(){
console.log("fn");
}
let zhangsan = new Person();
}
/*
为什么构造函数比构造函数 使用多:
1.方法在公共空间里面(prototype)
2.创建的对象的指向问题 : 构造函数有constructor
*/
}
原型链
{
// 原型链
function Foo(name){
this.name = name;
this.age = 20;
// this.test = "你好";
}
//原型: 也是对象 所以也就有__proto__,__proto__也是对象所以也还有原型...
Foo.prototype.fn = function(){
console.log("fn");
}
// Foo.prototype.test = "原型_你好";
let newFoo = new Foo("张三");
let obj = new Object();//所有的对象都是来自于 Object;
Object.prototype.test = "系统原型_你好";
// 所以最终的结果是;
console.log(Object.prototype.__proto__);
// 那原型链有啥用: 查找规则: 如果构造函数没有,就去原型,一步一步往原型链查找!||假如都有就是 就近原则
console.log(newFoo.test)
}