# javascript API

# Object.defineProperty()

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。 vue 数据双向绑定就是用这个实现的

# 语法

Object.defineProperty(obj, prop, descriptor)

# 参数

  • obj 要在其上定义属性的对象。
  • prop 要定义或修改的属性的名称。
  • descriptor 将被定义或修改的属性描述符。

# 属性

  • value 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
  • writable 仅当仅当该属性的writable为 true 时,该属性才能被赋值运算符改变。默认为 false
  • enumerable 仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false
  • configurable 仅当该属性的 configurable 为 true 时,该属性才能够被改变,也能够被删除。默认为 false

# 举例说明

const obj = {}

Object.defineProperty(obj,'name',{
    value:'码不停息',
    writable:true, //可被赋值运算符改变
    enumerable:true, // 可枚举
    configurable:true, // 可被编辑
    
  
})
let bvalue;
Object.defineProperty(obj,'age',{
    get(){
        return bvalue
    },
    set(newValue){
        bvalue = newValue
    }
})
obj.age = 18

// 此时的bvalue == obj.age ==  18

# Proxy(ES6)

Vue3.0 中将会通过 Proxy 来替换原本的 Object.defineProperty 基本操作:

let p = new Proxy(target, handler)

target 代表需要添加代理的对象,handler 用来自定义对象中的操作,比如可以用来自定义 set 或者 get 函数。

  • get
let obj = {name:'码不停息',age:18};
const pro = new Proxy(obj,{
   get: function(target, key,receiver){
        return key in target ? target[key] : '无此key';
    }
})

console.log(pro.name) // 码不停息
console.log(pro.aaa) // 无此key

get方法接收三个参数。target是实例化Proxy时使用的对象;而key是这次读取操作中想要获取的属性名;最后一个参数receiver则是这个实例化的Proxy自身,即proxy

  • set

# Object.create()

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

const obj = {
    name:'码不停息',
    say(){
        console.log(this.name)
    }
}
const obj2 = Object.create(obj);

obj2.say() // 码不停息
obj2.__proto__ === obj // true

我们也常用此方法实现继承(可以看JavaScript进阶中的继承章节)

# object.hasOwnProperty()

hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性,该方法会忽略掉那些从原型链上继承到的属性。

 const obj = {
     name:'码不停息'
 }
 console.log(obj.hasOwnProperty('name')) // true
 

此方法常用作 遍历一个对象的所有自身属性
通过for...in循环对象的所有枚举属性,然后再使用hasOwnProperty()方法来忽略继承属性

const obj ={
    name:"陌上寒",
    sex:"male"
}
for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
        console.log(`${key}: ${obj[key]}`)
    }
    else {
        console.log(key); 
    }
}

# IsPrototypeOf()

isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

# node.nodeType

# Object.freeze()

Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。

const obj = {
  prop: 42
};

Object.freeze(obj);

obj.prop = 33;

console.log(obj.prop);  //42

# Object.entries()

方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)

const object1 = {
  a: 'somestring',
  b: 42
};

// Object.entries(object1) 
// [["a", "somestring"],["b", 42]]
for (let [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}