- 普通new:
function Person(name, age) {
this.name = name;
this.age = age;
}
const p = new Person("Navi", 18);
所以我们要模拟const p = myNew(Person, "Navi", 18)
代码:
function myNew(fn,...args){
if(typeof fn!=="function"){
throw new TypeError("fn must be a function")
}
//两步走,对function和Prototype分别击破
const obj=Object.create(fn.prototype)
//创建对象并指定原型。obj.__proto__===fn.prototype
//__proto__是上一级对象 prototype就是挂方法的
//例如调用obj.say,obj会先看自己的obj.say有没有,没有的话会去obj.__proto__找,也就是调用fn.prototype.say
//普通函数:有 prototype也有 __proto__
//普通对象:没有 prototype,有 __proto__
let ret=fn.call(obj,...args)//执行构造函数,指定this是obj
//如果构造函数主动返回对象,就返回它,否则返回 obj
return ret instanceof object?ret:obj
}
调用例如:
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.say = function() {
console.log(`我是${this.name},今年${this.age}岁`)
}
const p = myNew(Person, "Navi", 18)
老 JS:构造函数 + prototype ≈ 类 现代 JS:class 是更好看的语法,但底层还是原型机制。
class Person {
constructor(name) {
this.name = name;
} //constructor就是构造函数
//对象方法
say() {
console.log(this.name);
}
}
- 深浅拷贝 浅拷贝:外层是新的,内层对象还是共用的。 深拷贝:外层和内层对象全都是新的。
function shallowCopy(obj) {
const newObj = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
//这里key是变量,只能这样写。不能写obj.key,他的意思是访问名字是"key"的属性。
}
}
return newObj;
}
function deepCopy(obj) {
//输入的不一定是个对象
if (obj instanceof Date) return new Date(obj);
if (obj instanceof Error) return new Error(obj.message);
if (obj instanceof RegExp) return new RegExp(obj);
if (obj instanceof Function)
return function (...args) {
return obj.call(this, ...args);
};
//因为typeof(null)=='object',所以需要拦住是null的情况直接返回
if (!obj || typeof obj !== "object") {
return obj;
}
const newObj = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
//hasOwnProperty,确保这个key是他自己的属性,而不是他从原型继承的
//因为for in会遍历所有key,包括继承来的。(遍历对象及其原型链上的可枚举属性)
if (typeof obj[key] === "object") {
newObj[key] = deepCopy(obj[key]);
//递归
} else {
newObj[key] = obj[key];
}
}
}
return newObj;
}
- instanceof 用法:
function Person() {}
const p = new Person();
p instanceof Person; // true
代码:
function myInstanceOf(left, right) {
const prototype = right.prototype;
let proto = Object.getPrototypeOf(left); //也就是获得left.__proto__(left所继承的原型)
while (true) {
if (proto === null) return false;
if (proto === prototype) return true; //两者相等,left就是right的实例
proto = Object.getPrototypeOf(proto); //这个是object内置对象上面的方法
}
}