【JS】构造函数

112 阅读4分钟

面向对象

面向对象是一种编程思想。

对象:万物皆对象

类:以数组为例,Array是一个类

实例:每一个具体的数组就是一个实例,且每个实例都可以调用Array这个类里面的公有方法,比如push方法,往数组末尾添加一项。

所有的实例都是对象。

所有的对象都是实例。

构造函数

一个普通函数在执行的时候,一旦前面加了 new 执行,这个函数就变成了构造函数,这个函数也可以被叫做 类 ,返回的结果就是当前这个类的实例。构造函数中的this就是当前的实例。

function Fn(){
  this.name = "Lily";
  this.age = 18;

}

var f1 = new Fn();
console.log(f1.name,f1.age);

//=> "Lily"  18

解析: f1 就是 Fn 这个类的一个实例,Fn 构造函数执行的时候,里面的this就是 f1 这个实例


return的几种情况

1.普通函数中如果没有return,返回值就是undefined,如果return了,返回值就是return的内容

2.构造函数执行,如果没有return,默认的返回值就是当前实例

3.构造函数执行,如果return的是一个基本数据类型,返回值还是当前实例,但是如果return的是一个引用数据类型,则返回值是这个引用数据类型


构造函数中的this

在构造函数中通过this添加的属性,都是给实例添加的"私有属性"。

判断某个对象是否具有某个属性

  • in判断一个对象是否具有某个属性(私有属性或者公有属性),只要有这个属性,就返回true,没有就返回false
var obj = {
  name:"LiLy"
}
console.log("name" in obj);
console.log("age" in obj);

=> true  false

  • hasOwnProperty判断一个对象是否具有某个私有属性,有这个私有属性就返回true,没有就返回false
var obj = {
  name:"LiLy"
}
console.log(obj.hasOwnProperty("name"));

//=> true

console.log("toString" in obj);
console.log(obj.hasOwnProperty("toString"));

//=> true  false

解析: 说明"toString"是obj的属性,但不是obj的私有属性,说明是obj的公有属性。


构造函数执行与普通函数执行的区别

构造函数执行过程中,代码执行前,会先自动创建一个空对象,开辟一个堆内存用来存储对象的属性,将函数中的this指向这个空对象,然后带有this的代码执行时就相当于给这个空对象添加属性,最后执行完毕,默认将这个对象返回。

构造函数和普通函数的区别

1.运行上的不同

普通函数:形成私有私有作用域-->形参赋值-->变量提升-->代码执行-->作用域是否销毁

构造函数:形成私有私有作用域-->形参赋值-->变量提升--> 默认生成一个空对象---> 让当前作用域的this指向这个空对象-->代码执行--> 默认把当前作用域的this return出去-->作用域是否销毁

2.执行上的区别

普通函数执行:函数名()

构造函数执行:new 函数名();如果构造函数执行不需要传递实参,可以省略执行小括号

3.如果在构造函数中手动return一个基本值,不会对返回值造成任何影响(不起作用);如果手动return一个引用值,那构造函数的返回值就会被改变,此时的构造函数就被破坏了,而且返回值已经不是当前类的实例了【不要轻易给构造函数手动return一个引用值】

实例相关

判断某个实例是否是某个类的实例

使用 instanceof 方法判断某个实例是否是某个类的实例。

function Fn(){
  this.name = "Lily";
  this.age = 18;

}

var f1 = new Fn();
console.log(f1 instanceof Fn);

//=> true

解析: 说明 f1 是 Fn 这个类的一个实例

每个实例都是独立的

function Fn(){
  this.name = "Lily";
  this.age = 18;

}

var f1 = new Fn();
var f2 = new Fn();
console.log(f1 === f2);

//=》false

解析: 每次构造函数执行都会重新开辟一个堆内存,f1 和 f2 都是 Fn 这个类的一个实例,是分别存储于两个不同的堆内存里面的,堆内存的地址不同,所以二者不是同一个实例,每个实例都是独立的一个对象。