Object方法和属性的介绍的MDN文档链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
Object方法
1)Object.create():创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
添加的方法是在原型上的
参数:
proto---新创建对象的原型对象,propertiesObject---可选。如果没有指定为 undefined,则是要添加到新创建对象的可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数
Object.create(proto, [propertiesObject])
返回值:一个新对象,带着指定的原型对象和属性
用途:实现类式继承
和传统的组合继承的区别就是在实现子类的原型的时候,传统方法是new 父类的构造函数,在这里是将Object.create()创建的对象赋值给子类的原型对象
// Shape - 父类(superclass)
function Shape() {
this.x = 0;
this.y = 0;
}
// 父类的原型方法
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info('Shape moved.');
};
// Rectangle - 子类(subclass),构造函数继承父类
function Rectangle() {
Shape.call(this); // call super constructor.
}
// 子类继承父类的原型属性和方法
Rectangle.prototype = Object.create(Shape.prototype); //和传统的组合继承的区别就在于这里
Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle();
console.log('Is rect an instance of Rectangle?',
rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?',
rect instanceof Shape); // true
rect.move(1, 1); // Outputs, 'Shape moved.'
使用混入的形式:即通过Object.create()和Object.assign()实现继承多个对象
function MyClass() {
SuperClass.call(this);
OtherSuperClass.call(this);
}
// 继承一个类 Object.create()
MyClass.prototype = Object.create(SuperClass.prototype);
// 混合其它 Object.assign()
Object.assign(MyClass.prototype, OtherSuperClass.prototype);
// 重新指定constructor
MyClass.prototype.constructor = MyClass;
MyClass.prototype.myMethod = function() {
// do a thing
};
2)Object.freeze(obj):冻结一个对象----不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。如果一个属性的值是个对象,则这个对象中的属性是可以修改的,除非它也是个冻结对象
返回值:返回传递的对象(改变原对象),而不是创建一个被冻结的副本
递归实现深冻结
// 深冻结函数.
function deepFreeze(obj) {
// 取回定义在obj上的属性名
var propNames = Object.getOwnPropertyNames(obj);
// 在冻结自身之前冻结属性
propNames.forEach(function(name) {
var prop = obj[name];
// 如果prop是个对象,冻结它
if (typeof prop == 'object' && prop !== null)
deepFreeze(prop);
});
// 冻结自身(no-op if already frozen)
return Object.freeze(obj);
}
obj2 = {
internal: {}
};
deepFreeze(obj2);
obj2.internal.a = 'anotherValue';
obj2.internal.a; // undefined 设置没有生效,说明属性已经冻结了
3)Object.seal(obj):封闭一个对象,阻止添加新属性;所有现有属性标记为不可配置(属性不可删除,属性不可重新定义成访问器属性)。当前属性的值只要可写就可以改变
返回值:返回被密封对象的引用(改变原对象),而不是创建一个被冻结的副本
4)Object.getOwnPropertyNames(obj):
返回值:Array,每一个元素是对象上的所有属性包括non-enumerable属性(除了Symbol/原型上的属性和方法)
NOTE:for....in Object.keys()都只能访问到enumerable类型属性
通过Object.getOwnPropertyNames(obj)和Object.keys()、Array.prototype.filter()得到对象上non-enumerable属性
var target = myObject;
var enum_and_nonenum = Object.getOwnPropertyNames(target);
var enum_only = Object.keys(target);
var nonenum_only = enum_and_nonenum.filter(function(key) {
var indexInEnum = enum_only.indexOf(key);
if (indexInEnum == -1) {
// Not found in enum_only keys,
// meaning that the key is non-enumerable,
// so return true so we keep this in the filter
return true;
} else {
return false;
}
});
console.log(nonenum_only);
5)Object.prototype.hasOwnProperty(prop)
返回值:boolean,对象上是否有该属性,和原型上的属性区分