1.Object.defineProperty(对象,属性,{writable:true,等}) 兼容性ie8+ 但ie8支持的不好,不建议在ie8中用。
可以定义对象的新属性,修改已有属性。但当enumerable或者configurable为false时是不能修改的,严格模式会报错
在用它创建新属性时,不指定enumerable,configurable,writable 默认都是false。
如果只是用它修改已有属性,则无此限制。
2.Object.getOwnPropertyDescription(对象,属性) es6新方法
可获取对象属性的enumerable,configurable,writable,及value值
3.老生长谈的设计模式
3.1
(1).isPrototypeOf() 测试原型对象与实例之间的关系
//Person.prototype指向实例原型
//person1是Person的实例
Person.prototype.isPrototypeOf(person1) //true
(2). Object.getPorpotypeOf() es6新方法
Object.getPorpotypeOf(person1) === Person.prototype //true
(3).hasOwnProperty() 判断一个属性存在于原型还是存在于实例
只有属性存在于实例中才会返回true
一个重要的例子:
let Obj={}
Obj.prototype.name = 'dhq';
let Obj1 = new Obj()
alert(obj1.hasOwnProperty('name'))//false //因为name在原型上
obj1.name= 'test';
alert(obj1.hasOwnProperty('name'))//true //因为name在实例上也有了
(4).in操作符 不论属性在原型还是在实例只要有就返回true
let Obj={}
Obj.prototype.name = 'dhq';
let Obj1 = new Obj()
alert('name' in obj1 ) //true
tip:in操作符结合hasOwnProperty()可以判断属性在实例还是在原型。
二者都为true,则属性在实例
in返回true,hasOwnProperty()返回false 则属性在原型
(5).Object.keys() 返回对象中所有可枚举的属性的字符串数组
(6).Object.getOwnPropotyNames() 返回对象中所有属性的字符串数组(无论是否可枚举)
3.2组合使用构造函数和原型模式
可以解决引用类型在原型中共享的问题
//构造函数
function Person(name) {
this.name = name,
this.friends = ['dhq','test']
}
//原型
Person.prototype = {
constructor: Person,
sayName: function() {
alert(this.name)
}
}
let person1 = new Person('dhq');
let person2 = new Person('who');
person1.friends.push('aa');
alert(person1.friends ) //'dhq,test,aa'
alert(person2.friends ) //'dhq,test'
alert(person2.friends===person1.friends ) //false
alert(person2.sayName===person1.sayName) //true
构造函数与原型合而为一的完美解决方案:
function Person(name) {
this.name = name,
this.friends = ['dhq','test'],
if(typeOf this.sayName!= "function"){
Person.prototype = {
sayName: function() {
alert(this.name)
}
}
}
}
let person1 = new Person('dhq');
person1.sayName();
//tip:这种方式之后不能在使用字面量的方式重改原型,原因就是会切断现有实例与新原型之间的联系。