<aside> 💡
引用类型皆为对象
</aside>
原型和原型链都是来源于对象而服务于对象的概念,所以我们要先明确一点:
JavaScript中一切引用类型都是对象,对象就是属性的集合。
Array类型、Function类型、Object类型、Date类型、RegExp类型等都是引用类型。
也就是说 数组是对象、函数是对象、正则是对象、对象还是对象。
<aside> 💡
构造函数的原型对象和对象原型的关系
</aside>
//**构造函数的prototype===对象的__proto__
//Son.prototype===son.__proto__**
function Son(){};
var son = new Son();
console.log(Son.prototype)//Son {}
console.log(son.__proto__)//Son {}
console.log(Son.prototype===son.__proto__)//true
**//Son.prototype===son.__proto__**
<aside> 💡
原型链污染的原因函数(对象合并)
</aside>
copy类复制函数,引起原型链污染
**function merge(target,source){
for (let key in source){
if (key in source && key in target){
merge(target[key], source[key])
}else {
target[key]= source[key]
}
}
}
1. //key是键!!!
2. //里面是个子递归,进行完全复制**
<aside> 💡
JSON.parse传参成功原型链污染
</aside>
__proto__被直接当做02的原型父类,不是键,不会复制!!!
function merge(target,source){
for (let key in source){
if (key in source && key in target){
merge(target[key], source[key])
}else {
target[key]= source[key]
}
}
}
let o1 ={}
let o2 = {a: 1, "__proto__": {b: 2}}
merge(o1,o2)
console.log(o1.a, o1.b)//1 2
o3 ={}
console.log(o3.b)//undefined
JSON.parse传参成功原型链污染
function merge(target,source){
for (let key in source){
if (key in source && key in target){
merge(target[key], source[key])
}else {
target[key]= source[key]
}
}
}
let o1 ={}
let o2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
merge(o1,o2)
console.log(o1.a, o1.b)//1 2
o3 ={}
console.log(o3.b)//2
<aside> 💡
constructor构造函数原型链污染
</aside>
constructor构造函数原型链污染!!!
**{
"id": 1,
"constructor": {
"prototype": {
"isAdmin": true
}
}
}**