obj.xxx();
当调用对象的某个方法时, 首先在对象自身找该方法,如果自身有该方法则调用成功, 如果没有则继续沿着由__proto__构成的原型链查找该方法, 如果一直到原型链的终点都没有找到则报错.
Object.prototype.constructor
Object.prototype.toString()
Object.prototype.toLocaleString()
Object.prototype.hasOwnProperty()
Object.prototype.isPrototypeOf()
var obj = { name: '李煜', age: 30, run: () => { console.log('running'); }, };
obj.run();
console.log(obj.toString());
判断一个属性是否在对象身上
1、hasOwnProperty() 在判断一个属性是否在对象身上时, 不会沿着原型链查找的(只会在对象自身身上查找)
var obj = { name: '李煜', age: 30, run: () => { console.log('running'); }, };
if (obj.hasOwnProperty('toString')) {
// if( 'toString' in obj ){
console.log('在obj身上');
} else {
console.log('不在obj身上');
}
2、 in 在判断一个属性是否在对象身上时, 会沿着原型链查找
var obj = { name: '李煜', age: 30, run: () => { console.log('running'); }, };
//if (obj.hasOwnProperty('toString')) {
if( 'toString' in obj ){
console.log('在obj身上');
} else {
console.log('不在obj身上');
}
isPrototypeOf() 判断一个对象 是否是某个函数的原型对象
结论: js中任何一个对象都可以看做是 Object这个顶层构造函数的实例对象
var obj = { name: '李煜', age: 30, run: () => { console.log('running'); }, };
if( Array.prototype.isPrototypeOf( Object ) ){
// if (Object.prototype.isPrototypeOf(RegExp)) {
console.log('是');
} else {
console.log('不是');
}
var obj = { name: '李煜', age: 30, run: () => { console.log('running'); }, };
// if( Array.prototype.isPrototypeOf( Object ) ){
if (Object.prototype.isPrototypeOf(RegExp)) {
console.log('是');
} else {
console.log('不是');
}
var obj = { name:'李煜',age:30, father:{ name:'',age:90, son:{name:'',age:10} } };
console.log( obj );
Object.defineProperty(obj, 'name', {
// writable:true,
set: function( newValue ){ //在set函数中不能 执行针对该属性的赋值操作,会导致函数的递归调用.
console.log('修改了name属性的值',newValue);
},
get: function(){ //在get函数中不能 执行获取该属性的操作, 会导致函数的递归调用.
console.log('获取了name属性的值');
return '李煜'+'!!!';
},
})
监听对象的所有属性
思路:
1.先用for in 遍历对象, 拿到对象的每个属性
2.用Object.defineProperty给对象的每个属性设置监听
作用: 传入一个对象, 对该对象的每个属性进行遍历并且监听.
function listenObj(obj){
for(var key in obj){
if( typeof obj[key] == 'object' ){ //如果某个属性是引用类型, 则递归遍历该属性
listenObj(obj[key]) //递归遍历该属性
}else{ //不是引用类型
Object.defineProperty(obj, key , {
set:()=>{ console.log('修改了属性的值'); },
get:()=>{ console.log('获取了属性的值'); }
})
}
}
}
listenObj(obj)
Proxy
var obj = { name: '李玉', age: 0, father: { name: '', age: 10 }, list: [] }
// new Proxy(对象, { set,get }) 实现了对象的整体监听, 不需要再写循环遍历+递归调用
// new Proxy 本质是对原有对象进行了一层包装, 生成一个新的包装对象, 这个包装对象实现了对象的监(并不是直接对原有对象进行监听 )
// oobj 是原有对象obj的 代理对象
console.log(obj);
var oobj = new Proxy(obj, {
set: (a, b, c) => { console.log('修改了obj对象', a, b, c) },
get: (a, b, c) => { console.log('获取了obj对象', a, b, c) }
})