属性在实例中还是在构造函数的prototype属性对象中+Array判断
js如何判断数组是Array类型
方法一: 使用instanceof方法
instanceof 用于判断一个变量是否某个对象的实例,左边操作数是一个对象,右边操作数是一个函数对象或者函数构造器。原理是通过判断左操作数的对象的原型链上是否具有右操作数的构造函数的prototype属性。
a instanceof b?alert("true"):alert("false") //注意b值是你想要判断的那种数据类型,不是一个字符串,比如Array。
举一个例子:
var arr=[];
console.log(arr instanceof Array) //返回true
方法二: 使用constructor方法
在W3C定义中的定义:constructor 属性返回对创建此对象的数组函数的引用,就是返回对象相对应的构造函数。从定义上来说跟instanceof不太一致,但效果都是一样的。
那么判断各种类型的方法:
console.log([].constructor == Array); //true
console.log({}.constructor == Object); //true
console.log("string".constructor == String); //true
console.log((123).constructor == Number); //true
console.log(true.constructor == Boolean); //true
注意:
使用instaceof和construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,这时判断该变量,Array ==object.constructor;会返回false;
原因:
1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。
2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array。
方法三: 使用Object.prototype.toString.call(arr) === '[object Array]'方法
function isArray(o) {
return Object.prototype.toString.call(o);
}
var arr=[2,5,6,8];
var obj={name:'zhangsan',age:25};
var fn = function () {}
console.log(isArray(arr)); //[object Array]
console.log(isArray(obj)); //[object Object]
console.log(isArray(fn)); //[object function]
方法四:ES5定义了Array.isArray:
Array.isArray([]) //true
1.hasOwnProperty()方法:可以检测一个属性是否存在于实例中还是原型对象中
function Person(){}; Person.prototype.name="Nicholas"; Person.prototype.age=29; Person.prototype.job="Software Engineer"; Person.prototype.sayName=function(){ alert(this.name); } var person1=new Person(); var Person2=new Person(); alert(person1.hasOwnProperty("name")); //false person1.name="Grey"; alert(person1.hasOwnProperty("name")); //true delete person1.name //删除属性 alert(person1.hasOwnProperty("name")); //false
2. in操作符
function Person(){}; Person.prototype.name="Nicholas"; Person.prototype.age=29; Person.prototype.job="Software Engineer"; Person.prototype.sayName=function(){ alert(this.name); } var person1=new Person(); var Person2=new Person(); alert(person1.hasOwnProperty("name")); //false alert("name" in person1); //true person1.name="Grey"; alert(person1.hasOwnProperty("name")); //true alert("name" in person1); //true delete person1.name //删除属性 alert(person1.hasOwnProperty("name")); //false alert("name" in person1); //true
name属性如论是在对象上还是在原型上,调用in操作符 都返回true
因此,同时使用hasOwnProperty()方法和in操作符,就可以确定该属性到底是存在于实例对象中还是存在原型对象上。
3.hasPrototypeProperty()
function Person(){}; Person.prototype.name="Nicholas"; Person.prototype.age=29; Person.prototype.job="Software Engineer"; Person.prototype.sayName=function(){ alert(this.name); } var person=new Person(); alert(hasPrototypeProperty(person,"name")); //true person1.name="Grey"; alert(hasPrototypeProperty(person,"name")); //false
上例中,name属性先是存在于原型中,因此hasPrototypeProperty()返回true;当在实例中重写name属性,即使在原型中仍然有name属性,hasPrototypeProperty()仍然返回false.
4. for-in循环:返回所有能够通过对象访问的、可枚举的属性,其中既包括存在于实例中的属性,也包括存在于原型中的属性
Person.prototype.name="Nicholas"; Person.prototype.age=29; Person.prototype.job="Software Engineer"; Person.prototype.sayName=function(){ alert(this.name); } var person=new Person(); person.x=1; person.y=2; person.z=3; for(var prop in person){ console.log(prop+": "+person[prop]); }
5. Object.keys(obj)与Object.getOwnPropertyNames(obj)
Object.keys(obj)方法接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组。
Object.getOwnPropertyNames(obj)方法返回所有的属性无论是否可枚举
function Person(){} Person.prototype.name="Nicholas"; Person.prototype.age=29; Person.prototype.job="Software Engineer"; Person.prototype.sayName=function(){ alert(this.name); } var person=new Person(); person.x=1; person.y=2; person.z=3; var keys1=Object.keys(person); var keys2=Object.keys(Person.prototype); var keys3=Object.getOwnPropertyNames(person); var keys4=Object.getOwnPropertyNames(Person.prototype); console.log(keys1); //["x","y","z"] console.log(keys2); //["name","age","job","sayName"] console.log(keys3); //["x","y","z"] console.log(keys4); //["constructor","name","age","job","sayName"]