1、自有属性与原型属性
- 自有属性:构造函数本身的属性。通过对象的引用添加的属性。其他对象可能无此属性;即使有,也是彼此独立的属性
- 原型属性:通过原型所定义的属性。用于共享属性和方法。从原型对象中继承来的属性,一旦原型对象中属性值改变,所有继承自该原型的对象属性均改变。
//定义构造函数
function Dog(name){
//构造函数本身的属性 --自有属性
this.name = name;
this.sayName = function (){
console.log("This name is " + this.name + "." );
}
}
//通过构造函数的prototype方法新增属性或方法
//通过原型所定义的属性 --原型属性
Dog.prototype.numLegs = 4;
/**
通过构造函数创建Dog对象时,不仅具有自有属性,还具有构造函数的原型属性
*/
let dog = new Dog('Jeff');
console.log(dog);
console.log(dog.name); //Jeff
console.log(dog.numLegs); //4
//注意:name属性的值可以动态改变,原型属性numLegs的值不能动态改变。
let dog = new Dog('Tom');
console.log(dog);
console.log(dog.name); //Tom
console.log(dog.numLegs); //4
2、重写属性
原有属性比原型属性的优先级高,原型属性不能重写原有属性的值。
可以给对象增加与原型属性名相同的自有属性,后续会默认访问自有属性。
//定义构造函数
function Dog(name){
this.name = name;
}
//通过原型定义name属性
Dog.prototype.name = "Tom";
Dog.prototype.numLegs = 4;
//创建对象并定义自有属性name
let dog =new Dog("Jeff");
//自有属性与原型属性同名时,默认访问的是自有属性的值 -> 自有属性的优先级高于原型属性
console.log(dog.name); //Jeff
//删除对象的自有属性
delete dog.name;
//重新访问对象的属性,此时获取的是对象的原型属性,通过测试发现 自有属性比原型属性优先级高,但不会覆盖掉原型属性
console.log(dog.name); //Tom
//给对象增加与原型属性名相同的自有属性,后续会默认访问自有属性。
console.log(dog.numLegs); //4
dog.numLegs = 6;
console.log(dog.numLegs); //6
3、检测属性是自有属性还是原型属性
- 使用hasOwnPropertype()方法检测对象属性是否是自有属性:
Object.hasOwnProperty(property)方法
作用: 判断指定属性是否是对象的自有属性
property: 表示指定属性名称
返回值为布尔值,true 表示存在指定的自有属性,false表示不存在指定的自有属性
- 使用in关键字检查属性是否是对象及其原型中的属性
function Bird(name) {
this.name = name; //own property
}
Bird.prototype.numLegs = 2; // prototype property
let duck = new Bird("Donald");
let ownProps = [];
let prototypeProps = [];
for (let property in duck) {
if(duck.hasOwnProperty(property)) {
ownProps.push(property);
} else {
prototypeProps.push(property);
}
}
console.log(ownProps);
console.log(prototypeProps);
console.log("name" in duck ); //true
console.log("numLegs" in duck ); //true