-
使用原型对象的好处是可以让所有对象实例共享它所包含的属性,而构造函数中,每个方法都要在每个实例上重新创建一遍
/*
Object.getOwnPropertyDescriptor(obj,property) 用于获取实例对象的属性
Object.getPropertypeOf(obj) 在所有支持实现中 这个方法返回[[prototype]]值 ===obj.prototype
Object.keys(obj) 要取得对象上所有可枚举的实例属性
Object.getOwnPropertyNames() 要得到所有实例属性,无论它是否可枚举
*/
//定义一个Person构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
let c = new Person("陈航", "20") //实例化一个c对象
Person.prototype.job = "Software Engineer"; //Person的原型中添加job属性
//判断一个属性是否为原型中的属性
function hasPrototypeProperty(object, property) {
return !object.hasOwnProperty(property) && (property in object)
// hasOwnProperty() 只在属性存在于实例中时才返回 true
// in 操作符只要通过对象能够访问到属性就返回 true
}
console.log(c); //Person {name: "陈航", age: "20"}
console.log(c.job); //Software Engineer
console.log(
hasPrototypeProperty(c, "job") //true
);
console.log(
hasPrototypeProperty(c, "name") //false
);
-
in操作符
在 IE 中,由于其实现认为原型的 toString() 方法被打上了值为 false 的 [[Enumerable]] 标记,因此应该跳过该属性,结果我们就不会看到警告框
-
原型对象使用对象字面量方式定义属性会重写,constructor不在指向构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
address: "地址",
show: function() {
console.log(this.address);
}
}
var person1 = new Person("person01", 20);
console.log(person1); //Person {name: "person01", age: 20}
console.log(Person.prototype.constructor);
/*
控制台输出 Object()
说明:原型对象使用字面量方法创建后 constructor属性不在指向Person构造函数了 而是指向Object对象
*/
如果我们需要获取构造函数(类)名,我们需要通过自定义设置constructor的指向
/*
以这种方式重设 constructor 属性会导致它的 [[Enumerable]] 特性被设置为 true。
默认情况下,原生的 constructor 属性是不可枚举的
*/
Person.prototype = {
constructor: Person,
address: "地址",
show: function() {
console.log(this.address);
}
}
所以我们换使用Object.defineProperty(obj,property,options)方法
//使用Object.defineProperty()方法设置对象内部数据属性
Object.defineProperty(Person.prototype, "constructor", {
//[[Enumerable]] :表示能否通过 for-in 循环返回属性。这个特性默认值为 true 。
enumerable: false,
value: "Person"
})