//主入口函数
const readonlyMap = new WeakMap();
const objectToString = Object.prototype.toString;
const readonlyGet = createGetter(true);
function createGetter(isReadonly = false, shallow = false) {
return function get(target, key, receiver) {
if (key === "__v_isReactive" /* IS_REACTIVE */) {
return !isReadonly;
}
else if (key === "__v_isReadonly" /* IS_READONLY */) {
return isReadonly;
}
else if (key === "__v_raw" /* RAW */ &&
receiver ===
(isReadonly
? shallow
? shallowReadonlyMap
: readonlyMap
: shallow
? shallowReactiveMap
: reactiveMap).get(target)) {
return target;
}
const targetIsArray = isArray(target);
if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
return Reflect.get(arrayInstrumentations, key, receiver);
}
const res = Reflect.get(target, key, receiver);
if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
return res;
}
if (!isReadonly) {
track(target, "get" /* GET */, key);
}
if (shallow) {
return res;
}
if (isRef(res)) {
// ref unwrapping - does not apply for Array + integer key.
const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
return shouldUnwrap ? res.value : res;
}
if (isObject(res)) {
// Convert returned value into a proxy as well. we do the isObject check
// here to avoid invalid value warning. Also need to lazy access readonly
// and reactive here to avoid circular dependency.
return isReadonly ? readonly(res) : reactive(res);
}
return res;
};
}
const readonlyHandlers = {
get: readonlyGet,
//下面两个函数只要被执行,就会弹出报错,所以我们只需要重点看第一个get函数
set(target, key) {
{
console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
}
return true;
},
deleteProperty(target, key) {
{
console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
}
return true;
}
};
//主入口函数
function readonly(target) {
return createReactiveObject(target, true, readonlyHandlers, readonlyMap);
}
//类型判断函数
const isObject = (val) => val !== null && typeof val === 'object';
const isArray = Array.isArray;
const isSymbol = (val) => typeof val === 'symbol';
function createReactiveObject(target, isReadonly, baseHandlers, proxyMap) {
//传入isReadonly 值为true,判断传入的值是否为除Null 以外的Object对象,如果不是的话就会弹出错误,
if (!isObject(target)) {
{
console.warn(`value cannot be made reactive: ${String(target)}`);
}
return target;
}
// target is already a Proxy, return it.
// exception: calling readonly() on a reactive object
// 这些条件都满足的话说明传入的已经是一个reactive对象了 ,直接return 返回即可
if (target["__v_raw" /* RAW */] &&!(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
return target;
}
// 初始化时proxyMap 为空
console.log(proxyMap,'proxymap') //WeakMap { <items unknown> } proxymap
const existingProxy = proxyMap.get(target); //获取到的值为undefined
if (existingProxy) {
return existingProxy;
}
// only a whitelist of value types can be observed.
const targetType = getTargetType(target);
if (targetType === 0 /* INVALID */) {
return target;
}
console.log(targetType,'targetType')
const proxy = new Proxy(target, baseHandlers);
proxyMap.set(target, proxy);
return proxy;
}
function getTargetType(value) {
return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
? 0 /* INVALID */
: targetTypeMap(toRawType(value));
}
function targetTypeMap(rawType) {
switch (rawType) {
case 'Object':
case 'Array':
return 1 /* COMMON */;
case 'Map':
case 'Set':
case 'WeakMap':
case 'WeakSet':
return 2 /* COLLECTION */;
default:
return 0 /* INVALID */;
}
}
const toRawType = (value) => {
// extract "RawType" from strings like "[object RawType]"
return toTypeString(value).slice(8, -1);
};
const toTypeString = (value) => objectToString.call(value);
var result = readonly({a:2})
console.log(result)
控制台输出
//主入口函数
const readonlyMap = new WeakMap();
const readonlyCollectionHandlers = {
get: createInstrumentationGetter(true, false)
};
function createInstrumentationGetter(isReadonly, shallow) {
const instrumentations = shallow
? isReadonly
? shallowReadonlyInstrumentations
: shallowInstrumentations
: isReadonly
? readonlyInstrumentations
: mutableInstrumentations;
return (target, key, receiver) => {
if (key === "__v_isReactive" /* IS_REACTIVE */) {
return !isReadonly;
}
else if (key === "__v_isReadonly" /* IS_READONLY */) {
return isReadonly;
}
else if (key === "__v_raw" /* RAW */) {
return target;
}
return Reflect.get(hasOwn(instrumentations, key) && key in target
? instrumentations
: target, key, receiver);
};
}
const readonlyGet = createGetter(true);
function createGetter(isReadonly = false, shallow = false) {
//问题,proxy实现拦截
return function get(target, key, receiver) {
if (key === "__v_isReactive" /* IS_REACTIVE */) {
return !isReadonly;
}
else if (key === "__v_isReadonly" /* IS_READONLY */) {
return isReadonly;
}
else if (key === "__v_raw" /* RAW */ &&
receiver ===
(isReadonly
? shallow
? shallowReadonlyMap
: readonlyMap
: shallow
? shallowReactiveMap
: reactiveMap).get(target)) {
return target;
}
const targetIsArray = isArray(target);
if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
return Reflect.get(arrayInstrumentations, key, receiver);
}
const res = Reflect.get(target, key, receiver);
if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
return res;
}
if (!isReadonly) {
track(target, "get" /* GET */, key);
}
if (shallow) {
return res;
}
if (isRef(res)) {
// ref unwrapping - does not apply for Array + integer key.
const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
return shouldUnwrap ? res.value : res;
}
if (isObject(res)) {
// Convert returned value into a proxy as well. we do the isObject check
// here to avoid invalid value warning. Also need to lazy access readonly
// and reactive here to avoid circular dependency.
return isReadonly ? readonly(res) : reactive(res);
}
return res;
};
}
const readonlyHandlers = {
get: readonlyGet,
//下面两个函数只要被执行,就会弹出报错,所以我们只需要重点看第一个get函数
set(target, key) {
{
console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
}
return true;
},
deleteProperty(target, key) {
{
console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
}
return true;
}
};
//主入口函数
function readonly(target) {
return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
}
//类型判断函数
const isObject = (val) => val !== null && typeof val === 'object';
const isArray = Array.isArray;
const isSymbol = (val) => typeof val === 'symbol';
function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
//传入isReadonly 值为true,判断传入的值是否为除Null 以外的Object对象,如果不是的话就会弹出错误,
if (!isObject(target)) {
{
console.warn(`value cannot be made reactive: ${String(target)}`);
}
return target;
}
// target is already a Proxy, return it.
// exception: calling readonly() on a reactive object
// 这些条件都满足的话说明传入的已经是一个reactive对象了 ,直接return 返回即可
if (target["__v_raw" /* RAW */] &&!(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
return target;
}
// 初始化时proxyMap 为空
const existingProxy = proxyMap.get(target);
if (existingProxy) {
return existingProxy;
}
// only a whitelist of value types can be observed.
//
const targetType = getTargetType(target); //判断传入的数据类型,如果是Object类型数据 返回值一般为1
if (targetType === 0 /* INVALID */) {
这里是因为数据类型不满足要求,所以直接把数据返回了出去
return target;
}
//这里一般调用传入的handlers是 baseHandlers 这里调用的传入的是readonlyHandlers 所以转到这个readonlyHandlers继续阅读
const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
proxyMap.set(target, proxy);
return proxy;
}
const objectToString = Object.prototype.toString;
function getTargetType(value) {
//初始化的时候值为false 返回的三元表达式后半部分调用了targetTypeMap()函数,传入了另一个函数toRawType()并且给它传入value
//值
return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
? 0 /* INVALID */
: targetTypeMap(toRawType(value));
}
function targetTypeMap(rawType) {
//这里进行判断 如果是传入的类型是'Object'和'Array' 返回1
//传入数据类型 为 'Map' ,'Set','WeakSet' ,'WeakMap' 返回2
//其他的数据类型返回为 0
switch (rawType) {
case 'Object':
case 'Array':
return 1 /* COMMON */;
case 'Map':
case 'Set':
case 'WeakMap':
case 'WeakSet':
return 2 /* COLLECTION */;
default:
return 0 /* INVALID */;
}
}
const toRawType = (value) => {
// extract "RawType" from strings like "[object RawType]"
//提取Object.prototype.string.call(value) 的数据类型
return toTypeString(value).slice(8, -1);
};
const toTypeString = (value) => objectToString.call(value);