面向对象
面向对象是一种编程思想。
对象:万物皆对象
类:以数组为例,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 这个类的一个实例,是分别存储于两个不同的堆内存里面的,堆内存的地址不同,所以二者不是同一个实例,每个实例都是独立的一个对象。