欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

javascript上Object的方法简单介绍

程序员文章站 2024-03-18 20:51:04
...

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对象上是否有该属性,和原型上的属性区分