理解Javascript的动态语言特性(5)

也就是说每个实例内部都有一个指针指向与Dog.prototype;ECMAScript5增加了一个新方法,Object.getPrototypeOf();这个方法可以返回属性值;还是如上面的代码:

function Dog() {}; Dog.prototype = { name: 'wangwang', age:'11', say: function(){ alert(this.name); //wangwang } } var dog1 = new Dog(); var dog2 = new Dog(); console.log(Object.getPrototypeOf(dog1) === Dog.prototype); //true console.log(Object.getPrototypeOf(dog1).name);//wangwang

使用Object.getPrototypeOf()可以方便地取得一个对象的原型,而这在利用原型实现继承的情况下是非常重要的。

支持这个方法的浏览器有IE9+、Firefox 3.5+、Safari 5+、Opera 12+和Chrome。

每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性。搜索首先从对象实例本身开始。如果在实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。如果在原型对象中找到了这个属性,则返回该属性的值。

虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加了一个属性,而该属性与实例原型中的一个属性同名,那我们就在实例中创建该属性,该属性将会屏蔽原型中的那个属性。

比如如下代码:

function Dog() {}; Dog.prototype = { name: 'wangwang', age:'11', say: function(){ alert(this.name); //wangwang } } var dog1 = new Dog(); var dog2 = new Dog(); dog1.name = "aa"; console.log(dog1.name);// aa console.log(dog2.name);// wangwang

还是我们刚刚上面说的,对象查找的方式是查找2次,先查找实例中有没有这个属性,如果对象的实例有这个属性的话,直接返回实例中的属性值,否则的话继续查找原型中的属性值,如果有则返回相对应的值,否则的话返回undefined,如上我们先给dog1的实例一个name属性,那么再次查找的话,那么查找的是实例中的name属性,但是实例dog2查找的还是原型中的name属性;但是如果我们需要让其查找原型的name属性的话,我们可以使用delete删除这个实例中的name属性;如下代码:

function Dog() {}; Dog.prototype = { name: 'wangwang', age:'11', say: function(){ alert(this.name); //wangwang } } var dog1 = new Dog(); var dog2 = new Dog(); dog1.name = "aa"; console.log(dog1.name);// aa console.log(dog2.name);// wangwang delete dog1.name; console.log(dog1.name);// wangwang

但是我们可以使用hasOwnProperty()方法可以检测一个属性是存在实例中,还是存在原型中,如下测试代码:

function Dog() {}; Dog.prototype = { name: 'wangwang', age:'11', say: function(){ alert(this.name); //wangwang } } var dog1 = new Dog(); var dog2 = new Dog(); console.log(dog1.hasOwnProperty("name")); // false dog1.name = "aa"; console.log(dog1.name); // aa console.log(dog1.hasOwnProperty("name")); // true console.log(dog2.name); // wangwang console.log(dog2.hasOwnProperty("name")); // false delete dog1.name; console.log(dog1.name); // wangwang console.log(dog1.hasOwnProperty("name")); //false

理解原型与in操作符

有2种方式使用in操作符,单独使用和在for-in循环中使用,在单独使用中,in操作符会在通过对象访问给定属性时返回true,不管它是在实例中还是在原型中,比如如下代码:

function Dog() {}; Dog.prototype = { name: 'wangwang', age:'11', say: function(){ alert(this.name); //wangwang } } var dog1 = new Dog(); console.log("name" in dog1); // true dog1.name = "aa"; console.log("name" in dog1); //true

上面代码中,name属性无论是在实例中还是在原型中,结果都返回true,我们可以通过in和hasOwnProperty()方法来确定属性是不是在原型当中,我们都知道in不管是在实例中还是在原型中都返回true,而hasOwnProperty()方法是判断是不是在实例中,如果在实例中返回true,那么我们取反就不在实例当中了;如下代码封装:

function hasPrototypeProperty(object,attr){ return !object.hasOwnProperty(attr) && (attr in object); }

如下测试代码:

function Dog() {}; Dog.prototype = { name: 'wangwang', age:'11', say: function(){ alert(this.name); //wangwang } } var dog1 = new Dog(); function hasPrototypeProperty(object,attr){ return !object.hasOwnProperty(attr) && (attr in object); } console.log(hasPrototypeProperty(dog1,'name')); //true 在原型中 dog1.name = 'aa'; console.log(hasPrototypeProperty(dog1,'name')); //false 在实例中

for-in

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgdxzg.html