function foo(){} foo.prototype.z = 3; var obj = new foo(); obj.y = 2; obj.x = 1; obj.x; //1 obj.y; //2 obj.z; //3 typeof obj.toString; //‘function‘ ‘z‘ in obj; //true obj.hasOwnProperty(‘z‘); //false
首先,我们通过function foo()去定义一个函数对象。。那么,foo()对象自动带有prototype对象属性,如图所示添加了z属性。再通过new构造器,构造obj对象,如图所示,obj的原型指向构造器的prototype属性也就是foo.prototype。
再看例子:obj.x和obj.y会在obj对象上找到x,y属性,而obj上没有z属性,当obj.z时,obj上没有z,此时就会查找原型上的属性,发现z=3。
foo.prototype的原型是Object.prototype,Object.prototype的原型是null。Object.prototype的作用是:如图所示,typeof obj.toString是一个‘function’,而在ibj以及它的原型上都找不到toString方法,而js中默认的对象上基本都有toString方法,是因为他们的原型指向null之前都会指向Object.prototype,toString正是Object.prototype上的方法。
obj. hasOwnProperty(‘z‘)返回false,表示z属性并不是直接为obj的属性。
obj.z = 5; obj.hasOwnProperty(‘z‘); //true foo.prototype.z; //still 3 obj.z; //5 obj.z = undefined; obj.z; //undefined delete obj.z; //true obj.z; //3 delete obj.z; //true obj.z; //still 3!!!
像代码中所写,obj.z = 5;对于赋值来说,先在obj对象上查找,如果没有,此时不会在原型链中查找,而是在这个对象上添加z=5;foo.prototype.z依旧为3。
当obj.z=undefined时,obj对象上z属性的值被修改为undefined,所以返回undefined时不一定代表不存在。
当delete obj.z后,拿到z的值为原型上的z的值。obj上的z属性已经被删除。
原型链上大部分属性的 Enumerable(可枚举)标签都是false,也就是说console.log一个对象的时候都只显示自己的对象,而在控制台能看到很多属性
属性标签有:value:true,writeable:true(是否可写),enumerable:true(是否可枚举),configurable:true(表示前面这些属性是否可修改)