1. 程式人生 > >hasPrototypeProperty(Obj,propertyName),for-in和in的區別

hasPrototypeProperty(Obj,propertyName),for-in和in的區別

例項上的屬性和方法大致可以分為兩種,一種是在例項上的,一種是在原型物件上的。

在建構函式內部使用this宣告的屬性和方法,在建立例項時會繫結到例項上。在原型物件上宣告的屬性和方法在原型物件上。

物件尋找某個屬性或者會先在例項上尋找,然後再去原型物件上尋找。即使是例項上用有某個屬性或者方法,原型物件上同名的屬性或者方法依然會存在,只是例項會優先使用自身例項上的屬性和方法。

如果要刪除例項上的方法可以使用delete方法,delete(ObjectName,PropertyName);

可以使用hasPrototypeProperty()來判斷一個物件的某個屬性是在例項上還是在原型物件上。

hasPrototypeProperty(ObjectName,PropertyName)

如果在例項上擁有這個屬性,則返回true;

與hasPrototypeProperty()方法有區別的是in操作符,使用in可以判斷某個屬性是否可以被物件訪問,不管這個屬性是在例項上還是在原型物件上。

關於for-in和in的區別在下面的DEMO中可以演示

<script type="text/javascript">
			 function Person(){
				Person.prototype.name='八戒';
				Person.prototype.age=18;
			}
			 
			var person=new Person();
			
			alert(person.name);//八戒
						
			
			alert('name' in person);//true
			
			Object.defineProperty(person.__proto__,"name",{
				//將原型物件上的name屬性設定為不可訪問
				value:'悟空',
				enumerable:false
			});
			
			alert(person.name);//悟空
			
			//使用in語句,確認屬性是否可以被物件訪問,這裡即使name被設定為不可列舉,但是依然可以訪問;	
			alert('name' in person);//true			
			
			//使用for-in迴圈時,返回的是所有可以通過物件訪問並且可列舉的屬性,因為上面設定了enumerable為false,
		//所以下面只輸出age;
			for( var prop in person ){
				console.log(prop);//只有age
			}
			
		</script>

所以總結一下就是:hasPrototypeProperty()確認屬性是否在例項上,in確認屬性是否可以被物件訪問,for-in確認物件是否可以被物件例舉(正常情況下使用for-in迴圈出的屬性包括例項屬性和原型物件屬性);

另外如果需要得到所有的例項屬性,無論屬性是否可以列舉,可以使用getOwnpropertyName(),DEMO如下:

<script type="text/javascript">
			 function Person(){
				Person.prototype.name='八戒';
				Person.prototype.age=18;
			}
			 
			var person=new Person();
			person.address='高老莊';
			person.job='天蓬元帥';
			
			Object.defineProperty(person,'job',{
				enumerable:false
			})
			var keys=Object.getOwnPropertyNames(person);
			alert(person.job);//天蓬元帥
			console.log('person的例項方法:'+keys);//adress,job
			console.log(Array.isArray(keys));//true
			
			for(var prop in person){
				console.log(prop);//adress,name,age
			}
			
		</script>