📅  最后修改于: 2023-12-03 14:50:31.547000             🧑  作者: Mango
在 JavaScript 中,每个对象都有一个原型对象,对象可以通过它的原型对象继承属性和方法。原型反应就是通过原型链修改对象的原型属性,从而引发一系列联动反应的过程。
每一个 JavaScript 对象都有一个原型对象,它包含了一组共享的属性和方法。当试图访问一个对象的属性或方法时,如果该对象本身没有定义该属性或方法,则 JavaScript 引擎会沿着该对象的原型链向上查找,直到找到该属性或方法为止。
let obj = { foo: 1 };
let obj2 = Object.create(obj); // Object.create() 创建 obj2 时,将 obj 作为 obj2 的原型
console.log(obj2.foo); // 1
在这个例子中,obj2
对象通过 Object.create()
的方式创建,它的原型为 obj
,因此 obj
中定义的 foo
属性可以被 obj2
继承并访问到。
原型反应指的是通过修改对象的原型属性,在 JavaScript 引擎中触发一系列联动反应的过程。比如:
let obj = { foo: 1 };
let obj2 = Object.create(obj);
console.log(obj2.foo); // 1
obj2.foo = 2;
console.log(obj2.foo); // 2
console.log(obj.foo); // 1
在这个例子中,我们先创建了对象 obj
和 obj2
,并将 obj2
的原型设置为 obj
。接着,我们修改了 obj2
对象的 foo
属性值为 2
,这个过程会导致 JavaScript 引擎中一系列链式反应的触发:首先,在 obj2
对象中创建一个新的 foo
属性,覆盖原型链上的 foo
属性;其次,在 obj2
对象中读取 foo
属性值时,JavaScript 引擎会首先查找对象本身是否定义了该属性,如果有则返回该值,如果没有,则会沿着原型链继续向上查找,直到找到 obj
对象并返回其 foo
属性的值。
因此,最终我们可以得到 obj.foo
的值为 1
,而 obj2.foo
的值为 2
。
原型反应可以用于实现 JavaScript 中的一些特殊功能,例如实现数据监听和双向绑定:
function Observable(obj) {
let observers = [];
function notify(prop, val) {
observers.forEach(observer => observer(prop, val));
}
let handler = {
get(target, prop) {
if (typeof target[prop] === 'object' && target[prop] !== null) {
return new Proxy(target[prop], handler);
}
return target[prop];
},
set(target, prop, val) {
target[prop] = val;
notify(prop, val);
return true;
}
};
return new Proxy(obj, handler);
}
let obj = { foo: 1 };
let obs = Observable(obj);
obs.foo = 2;
observers.push(function(prop, val) {
console.log(`property ${prop} changed to ${val}`);
});
obs.foo = 3;
// console output:
// property foo changed to 2
// property foo changed to 3
在这个例子中,我们定义了一个 Observable
函数,它接受一个对象参数 obj
。该函数返回一个代理对象 proxy
,通过修改 proxy
对象的原型链,我们可以在该对象上添加一组数据监听的功能。具体来说,我们使用了 JavaScript 中的 Proxy
对象来监听 proxy
对象的所有属性读取和修改操作,在修改属性时,通过原型反应的方式触发一系列联动反应,从而实现了数据监听的功能。
在 JavaScript 中,每个对象都有一个原型对象,对象可以通过它的原型对象继承属性和方法。原型反应就是通过原型链修改对象的原型属性,从而引发一系列联动反应的过程。原型反应可以用于实现 JavaScript 中的一些特殊功能,例如实现数据监听和双向绑定。