- 在编程的世界,程序通常可以分为:面向对象程序设计(OOP) 和 面向过程程序设计(POP)。
- 就面向对象而言,是指万物皆对象,然后我们根据一定的思维方式,对对象进行特定的抽离,让其划分为具体的类。我们再拿出这个类的实例进行研究。从这个实例上可以映射出对应类的特性。
面向对象的分类
-
JS本身就是基于面向对象开发的语言。
-
它可以划分为:内置类 和 自定义类
-
我们所用的数据类型,每一种都对应一个自己的数据类型
- 数字类:Number:每一个数字,包含NaN Infinity,这些都是Number类的实例
- 字符串类、布尔...: String、Boolean、BigInt、Object(Array、Date...)、Function
- Null、Undefined 这两个类是存在的,但是被浏览器保护起来了,是不让用
- Symbol 这个类有点特别,不能new
-
DOM元素也存在有自己的类和实例
dir(div): DIV 元素对象 --> HTMLDivElement --> HTMLElement ---> Element --> Node ---> EventTarget --> Objectdir(a): A元素对象 ---> HTMLAnchorElement ---> HTMLElement --> ...dir(document)document ---> HTMLDocument --> Document --> Node --> ...dir(window)window ---> Window ---> WindowProperties ---> EventTarget --> ...- 节点集合 --> NodeList --> Object
-
我们也可以设置 自定义类
- 类名的首字母一般是大写
- 每一个类都是函数数据类型的。
function Fun() { this.xxx = xxx }; Fun(); let fn = new Func(); log(fn);- 自定义类也是函数,所以也可以直接调用。直接掉哟个时候,就是普通函数执行。所以它有普通函数的特性:创建私有上下文、初始化作用域链、初始化THIS、初始化ARGUMENTS、形参赋值、变量提升、代码执行。
- 使用new 执行时,会将该函数当作类执行,此时的函数叫做类,返回的结果 称为当前类的实例。是一个实例对象。
构造函数和函数执行的区别
- 构造函数 和 普通函数 执行,大体是相同的。构造函数具备普通函数执行的业务链:初始化作用域链、初始化THIS、ARGUMENTS、形参赋值、变量提升、代码执行。
- 构造函数 比 普通函数 执行,多了一项创建对象和指向的过程
- 在初始化作用域链 和 初始化THIS 之间。构造函数执行会:
- 默认创建一个对象
- 让上下文中的THIS 指向这个对象
- this.xxx=xxx; 是给这个实例 创建 私有属性 和 方法
- 函数中的 RETRUN:如果是基本数据类型,那么返回这个创建的对象;如果返回引用类型,用这个类型代替创建出的对象。
检测方式
- 检测返回的对象,是不是这个类的实例
instanceoff instanceof Func - 检测某个属性是否是对象的属性 [无论公有还是私有]
in属性 in 对象 - 判断一个属性是当前对象的私有属性还是公有属性
hansOwnPrototypeObj.hasOwnPrototype(属性名)
prototype 和 __proto__
- 任何一个对象,都有很多的属性和方法,放在自己堆内存中的 是私有属性和方法。如果是基于
__proto__(原型链)找到对应 prototype(原型)上的属性和方法,这些是共有属性和方法。 - 每一个函数(包含内置类)都是Function 的一个实例,所以他们的
__proto__一定指向的是Function.prototype - 每一个对象(包含原型对象)都是Object 的实例,所以最后他们基于
__ptoto__一定可以找到Object.prototype
Object.create 原理
- 创建一个对象,然后让这个对象的
__proto__指向这个参数函数的prototype。 - 创建一个对象,可以将其理解为创建一个类的实例。然后让这个类的原型指向参数
Object.create = function create(prototype) {
function Func () {};
Func.prototype = prototype;
return new Func();
}
重写new
- new 的执行过程:
- 创建一个实例对象
- 让类当作普通函数执行
- THIS 指向这个实例对象
- 函数执行是否存在 RETURN,如果有查看数据类型
function _new(Func, ...args) {
let obj = Object.create(Func.prototype); // 创建实例对象,其this指向FUNC的prototype
let result = Func.call(obj, ...args); // 让函数执行,同时THIS发生改变
if(result !== 'null' && /^(object|function)$/.test(typeof result)) { // 判断RETURN
return result;
}
return obj;
}
来个题?
function Func (x,y) {
let num = x+y;
this.x = x;
this.y = y;
}
let f1 = Func(10,20);
let f2 = new Func(10,20);
- Func(): 当作普通函数执行,num作为私有上下文的私有属性。this执行window。没有return,所以为 undefined
- new Fun(): 当作构造函数执行。num依然是上下文的私有属性,new 会创造一个实例对象,this是给这个实例对象中赋予私有属性和方法。所以f2={x: 10, y: 20}