1. OOP
- OOP(Object Oriented Programming):面向对象程序设计
- POP(Procedure Oriented):面向过程程序设计
2. 类
实例 | 类 |
---|---|
1 | Number |
'A' | String |
true | Boolean |
null | Null->Object |
undefined | Undefined |
[] | Array |
/^$/ | RegExp |
function(){} | Function |
{} | Object |
每一个元素标签(元素对象)都有一个自己所属的大类
- div -> HTMLDivElement -> HTMLElement -> Element -> Node -> EventTarget -> Object
- 每一个实例可以调用所属类(整条链)中的属性和方法(原型链)
创建一个自定义类
- 创建一个函数(Function类的实例),直接执行就是普通函数,但是
new 执行
它则被称为一个自定义的类
NEW 函数执行
- 形成一个全新的执行上下文EC
- 形成一个AO变量对象
- ARGUMENTS
- 形参赋值
- 初始化作用域链
- 默认创建一个对象,而这个对象就是当前类的实例(比普通函数执行多的点)
- 声明其THIS指向,让其指向这个新创建的实例(比普通函数执行多的点)
- 代码执行
- 不论其是否写RETURN,都会把新创建的实例返回(特殊点)(比普通函数执行多的点)
// 普通函数执行
func(); //=>this:window AO(FUNC):{x=100}
// 当做new执行
function func() {
// let obj={}; //=>这个对象就是实例对象
// this 指向 obj
let x = 100;
this.num = x + 100; //=>相当于给创建的实例对象新增一个num的属性
// obj.num=200 (因为具备普通函数执行的一面,所以只有this.xxx=xxx才和创建的实例有关系,此案例中的x只是AO中的私有变量)
// return obj; 用户自己返回内容,如果返回的是一个引用类型值,则会把默认返回的实例给覆盖掉(此时返回的值就不在是类的实例了)
}
let f = new func();
console.log(f); //=>f是func这个类的实例 {num:200}
let f2 = new func();
console.log(f === f2); //=>false 每一次new出来的都是一个新的实例对象(一个新的堆内存)
//instanceof用来检测某一个实例是否属于这个类
console.log(f instanceof func); //=>TRUE
手写: 自己实现一个new
- 默认创建一个实例对象(而且是属于当前这个类的一个实例)
- 也会把类当做普通函数执行
- 执行的时候要保证函数中的this指向创建的实例
- 若客户自己返回引用值,则以自己返回的为主,否则返回创建的实例
function Dog(name) {
this.name = name;
}
Dog.prototype.bark = function () {
console.log('wangwang');
};
Dog.prototype.sayName = function () {
console.log('my name is ' + this.name);
};
/*
* 内置NEW的实现原理
* @params
* Func:操作的那个类
* ARGS:NEW类的时候传递的实参集合
* @return
* 实例或者自己返回的对象
*/
function _new(Func, ...args) {
// write your code here
//1. 默认创建一个实例对象(而且是属于当前这个类的一个实例)
// let obj = {}; // 这样不行,这样只创建了对象,原型没有指向Func.prototype
// 应该改变obj原型链: obj.__proto__ = Func.prototype; //=> 但是, IE大部分浏览器中不允许我们直接操作__proto__
let obj = Object.create(Func.prototype); //创建一个空对象,让这个空对象的.__proto__, 指向新地址。也就是,创建一个继承自Func.prototype的新对象
//2. 也会把类当做普通函数执行
//3. 执行的时候要保证函数中的this指向创建的实例
let result = Func.call(obj, ...args);
//4. 若客户自己返回引用类型,则以自己返回的为主,否则返回创建的实例
// typeof obj == 'obj' typeof array == 'obj' typeof function == "function"
// 因为 typeof null =="obj", 所以需要把把null排除
if ((result !== null && typeof result === "object") || (typeof result === "function")) {
return result;
}
return obj;
}
let sanmao = _new(Dog, '三毛');
sanmao.bark(); //=>"wangwang"
sanmao.sayName(); //=>"my name is 三毛"
console.log(sanmao instanceof Dog); //=>true
- let obj = Object.create(Func.prototype):
-
会将参数对象作为一个新创建的空对象的原型(让这个空对象的
.__proto__
, 指向新地址。), 并返回这个空对象 -
也就是,创建一个继承自Func.prototype的新对象。
-
- typeof:
- 实现Object.create()
//简略版
function myCreate(obj){
// 新声明一个函数
function C(){};
// 将函数的原型指向obj
C.prototype = obj;
// 返回这个函数的实力化对象
return new C()
}