构造函数、原型和类
lodash 原型污染漏洞: https://snyk.io/blog/snyk-research-team-discovers-severe-prototype-pollution-security-vulnerabilities-affecting-all-versions-of-lodash/
使用 function 定义(function *,async function,箭头函数都不行)的函数可以作为构造函数:
function A() {}
new A ==> {constructor: ƒ A()}
一个继承原型对象属性的对象,这样就定义了一个类
原型对象是类的唯一标识,定义构造函数可以算是定义类
原型对象跟 constructor 没有直接关系,修改 constructor 的 prototype 不会改变对象的原型(__proto__)
构造函数是用来初始化新创建的对象的,new 调用构造函数创建的对象
申明式创建的函数有一个 prototype 对象,其 constructor 属性指向自己。
创建原型为 o 的对象:Object.create(o);
对象原型一般用非标准 _proto_ 获取,或者 setPrototypeOf
console.log(Function instanceof Object); // true,构造函数 Object 的 prototype 是在对象 Function 的原型链上
console.log(Object instanceof Function); // true
// 函数之所以能调用,是因为有 [[Call]] 内部方法
模拟类继承:
// A 类是 B 类的父类,A 类的父类是 Object
// B 的实例会继承A类原型的属性
// 不能给类(构造函数)创建属性
// 类的 prototype 属性的构造函数要指向自己
// 类的各自实例创建属性不会影响,因为是通过类的原型实现的继承
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B
B.__proto__ = A // class 语法有这个,静态属性继承
// Object.create polyfill
// 注意: 常见的错误是使用 "new A()"来建立 B.prototype。直接new变成类似原型继承
// 这样做的错误之处有很多, 最重要的一点是我们在实例化时
// 不能赋予A类本身任何属性
function createObject(A.prototype) {
function ctor() { }
ctor.prototype = A.prototype;
return new ctor();
}