面向对象的属性、方法、操作符总结,都是干货。想深入掌握面向对象的程序设计模式,必须掌握一下知识点。下列知识点注重于实现,原理还请借鉴《javascript高级程序设计》
(基于javascript高级程序设计,总结出来的实用,常用方法属性和操作符)
1、标识构造函数对象实例的类型(构造函数的属性和操作符)
对象实例.constructor == 构造函数对象
在前面例子的最后,person1 和 person2 分别保存着 Person 的一个不同的实例。这两个对象都有一个 constructor(构造函数)属性,该属性指向 Person,如下所示。
1 alert(person1.constructor == Person); //true 2 alert(person2.constructor == Person); //true
对象实例 instanceof 对象
提到检测对象类型 instanceof 操作符更可靠,我们创建的所有对象既是object实例也是构造函数的实例。可以使用instanceof来验证
1 alert(person1 instanceof Object); //true 2 alert(person1 instanceof Person); //true 3 alert(person2 instanceof Object); //true 4 alert(person2 instanceof Person); //true
创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型;而这正是构造函数模式胜过工厂模式的地方。验证new操作符的实例对象和传统object创建方式的类型归属:
var obj = {
name:'s',
age:'s',
sex:'男'
}
alert(obj instanceof Object); // true
alert(obj instanceof Person); // false
//字面量方式创建的对象obj只属于object,并不属于其他对象,更没有办法让他具有特定类型。对比看来是不是构造函数的方式好的很多。
2、原型的方法:
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();
a、isPrototypeOf 用来确定实例person1/2是否指向了构造函数Person.prototype(原型对象) (这个指针就是__proto__ 或 [[Prototype]])-->隐士的存在
Person.prototype.isPrototypeOf(person1) //true Person.prototype.isPrototypeOf(person2) //true
b、Object.getPrototypeOf() 返回 __proto__ 或 [[Prototype]] 的指向
Object.getPrototypeOf(person1) // Person.prototype Object.getPrototypeOf(person1).name // Nicholas
c、person1.hasOwnProperty("name") 检测一个属性是存在于实例中,还是存在于原型中. 只在给定属性存在于对象实例中时,才会返回true
alert(person1.hasOwnProperty("name")); //false person1.name = "Greg"; alert(person1.name); //"Greg"——来自实例 alert(person1.hasOwnProperty("name")); //true alert(person2.name); //"Nicholas"——来自原型 alert(person2.hasOwnProperty("name")); //false delete person1.name; alert(person1.name); //"Nicholas"——来自原型 alert(person1.hasOwnProperty("name")); //false
注意:调用person1.hasOwnProperty( "name")时,只有当person1 重写name 属性后才会返回true,因为只有这时候name 才是一个实例属性,而非原型属性。
3、原型与in操作符
in:检测对象中是否有指定属性。in 操作符会在通过对象能够访问给定属性时返回 true,无论该属性存在于实例中还是原型中。
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 = "Greg"; alert(person1.name); //"Greg" ——来自实例 alert(person1.hasOwnProperty("name")); //true alert("name" in person1); //true alert(person2.name); //"Nicholas" ——来自原型 alert(person2.hasOwnProperty("name")); //false alert("name" in person2); //true delete person1.name; alert(person1.name); //"Nicholas" ——来自原型 alert(person1.hasOwnProperty("name")); //false alert("name" in person1); //true
注意:以上name属性,有在原型上的,有在对象上的。所以 "name" in person1 始终都返回 true。
同时使用 hasOwnProperty()方法和 in 操作符,就可以确定该属性到底是存在于对象中,还是存在于原型中。如下所示:
function hasPrototypeProperty(object, name) {
return !object.hasOwnProperty(name) && (name in object)
}
//name in object 只要存在于实例中或者原型上就返回 true
//如果object.hasOwnProperty(name)返回flase证明不存在于实例上,取反返回true。
注意:只要 in 操作符返回 true 而 hasOwnProperty()返回 false,就可以确定属性是原型中的属性。
下面看看自定义函数hasPrototypeProperty()的用法:
var person = new Person();
alert(hasPrototypeProperty(person, "name")); //true
person.name = "Greg";
alert(hasPrototypeProperty(person, "name")); //false
注意:
name 属性先是存在于原型中,因此 hasPrototypeProperty()返回 true。
当在实例中重写 name 属性后,该属性就存在于实例中了,因此 hasPrototypeProperty()返回 false。
4、Object.keys()方法
用来获得对象上可枚举的实例属性。接收一个对象作为参数,返回包含所有可枚举属性的字符串数组。
a、获得可枚举的属性
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var keys = Object.keys(Person.prototype);
alert(keys); //"name,age,job,sayName"
var p1 = new Person();
p1.name = "Rob";
p1.age = 31;
var p1keys = Object.keys(p1);
alert(p1keys); //"name,age"
keys方法可以获得所有可枚举属性的集合,使用for..in..也可以循环得出可枚举的属性。
可枚举属性:通俗的讲,我们自定义在实例或者原型上的属性是可枚举属性。拿原型举例子,实例化构造函数的实例下指向的原型有一个constructor就是实例的不可枚举属性。因为(枚举) enumerable
为false。
不可枚举属性:就是enumerable
为false的属性,使用for..in../Object.keys()/JSON.stringfy()都无法获取到。那么如何可枚举和不可枚举属性都获取到,如下:
b、获得所有可枚举属性和不可枚举属性的集合
Object.getOwnPropertyNames()
var keys = Object.getOwnPropertyNames(Person.prototype); alert(keys); //"constructor,name,age,job,sayName"
注意:结果中包含了不可枚举的 constructor 属性。Object.keys()和 Object.getOwnPropertyNames()方法都可以用来替代 for-in 循环。支持这两个方法的浏览器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和 Chrome
注意结果中包含了不可枚举的 constructor 属性。Object.keys()和 Object.getOwnPropertyNames()方法都可以用来替代 for-in 循环。支持这两个方法的浏览器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和 Chrome