js对象

2019-08-12  本文已影响0人  Super曲江龙Kimi

对象和原型

对象

若干属性的集合就是对象,一切引用类型都是对象,都是属性的集合

let arr = [1,2]
arr.name = 'kimi';
console.log(arr.length) // 2
console.log(arr.name) // 'kimi'

属性描述符

let obj = {
  a: 2
};
Object.getOwnPropertyDescriptor(obj, 'a');
// {
//  value: 2,
//  writable: true,
//  enumerable: true,
//  configurable: true
// }

<1> [[writable]]

表示是否能修改属性的值,默认值是true

let obj = {};
Object.defineProperty(obj, 'a', {
  value: 2,
  writable: false, // 不可写
  configurable: true,
  enumerable: true,
})
obj.a = 3; // 严格模式下会报错,非严格模式下会忽略
obj.a // 2

<2> [[configurable]] 默认值true

是否可以通过defineProperty来配置对象

let obj = {};
Object.defineProperty(obj, 'a', {
  value: 2,
  writable: true, 
  configurable: false, // 不可配置
  enumerable: true,
})
obj.a = 3; // 仍然可以修改属性值
obj.a // 3

Object.defineProperty(obj, 'a', {
  value: 2,
  writable: true, 
  configurable: true, // 不管什么模式都会报错
  enumerable: true,
})

如果使用Object.defineProperty创建新属性但是不填写配置,writable、configurable、enumerable默认都是false。

let obj = {};
Object.defineProperty(obj, 'a', {})
Object.getOwnPropertyDescriptor(obj, 'a');
// {
//  value: undefined,
//  writable: false,
//  enumerable: false,
//  configurable: false
// }

如果设置了configurable是false。仍然可以将writable的值从true设置为false,但是不可以从false设置为true。
如果设置了configurable是false,不可以使用delete删除属性

<3> [[value]] 默认值undefined

包含这个属性的数据值

<4> [[enumerable]] 默认值true

是否可以for in、object.keys、 JSON.stringify递归出来

访问描述符

[[get]] [[set]]

let obj = {};
Object.defineProperty(obj, 'a', {
  get: function() {
    return this._a;  
  },
  set: function(val) {
    this._a = val;
  } 
})
let obj = {
  get a() {
     return this._a;  
  },
  set a(val) {
    this._a = val
  }
}

以上两种都会在对象中创建一个不包含值的属性,自动调用get、set函数。如果设置了set、get则会忽略value和enumerable配置

不变性

<1> 设置writable、configurable为false

设置writable、configurable为false就可以创建一个真正的常量属性,不可修改、重定义、删除

<2> Object.preventExtensions() 不可扩展

let obj = {
  a: 2
};
Object.preventExtensions(obj) ; // 不可以添加新属性,并且保留已有属性
obj.b = 3 ;
obj.b // undefined 

<3> Object.seal() 密封

会在现有对象身上调用Object.preventExtensions,并把所有属性标记为configurable为false

不能添加新属性,也不能重新配置或者删除现有属性。可以修改现有的值

<4> Object.freeze() 冻结

会在现有对象身上调用Object.seal,并且把所有属性标记为writable为false

不能添加新属性,也不能重新配置或者删除现有属性。不可以修改现有的值

存在性

let obj = {
  a: undefined
}
obj.a // undefined
obj.b // undefined
都是undefined,如何来区分哪个为obj的属性呢?

hasOwnProperty()

hasOwnProperty只会判断自身是否有属性。in 操作符会检查属性是否存在原型中。

2 in [1,2]  // false 判断的是key 数组的key是下标 0,1

new操作符

  1. 创建一个空的简单JavaScript对象(即{});
  2. 链接该对象(即设置该对象的构造函数)到另一个对象;
  3. 将步骤1新创建的对象作为this的上下文 ;
  4. 如果该函数没有返回对象,则返回this。
function _new(fun) {
  return function() {
    // 创建一个空的简单JavaScript对象
    let obj = {};
    // 链接该对象(即设置该对象的构造函数)到另一个对象
    obj.__proto__: fun.prototype;
    // 将步骤1新创建的对象作为this的上下文
    let returnObj  = fun.apply(obj, arguments)
    // 如果该函数没有返回对象,则返回this
    if(typeof returnObj === 'object'){
        return returnObj
    }else{
        return obj
    }
  }
}

Object.create()

Object.create()方法创建一个新对象,并使用现有的对象来提供新创建的对象的proto

Object.create =  function (o) {
    var F = function () {};
    F.prototype = o;
    var newObj=new F();
    return newObj;
};

使用{}和Object.create(null)创建对象的区别。
Object.create(null)创建的对象proto为null。没有继承的方法例如toString()是一个完全空的对象。而{}继承于Object

上一篇下一篇

猜你喜欢

热点阅读