03月06, 2018

Javascript 的 Object

Object 的属性

Object.prototype

可以为所有 Object 类型的对象添加属性。

Object.prototype Object的原型

Object.prototype.constructor

特定的函数,用于创建一个对象的原型。Function.prototype.constructor等于本身。

Object.prototype.hasOwnProperty()

返回一个布尔值 ,表示某个对象是否含有指定的属性,而且此属性非原型链继承的。

function ClassMate(name,age) {
    this.name = name;
    this.age = age;
}

ClassMate.prototype.sex = "男"

let obj = new ClassMate("张三",18);
console.log(Object.hasOwnProperty("sex"))//false

Object.prototype.isPrototypeOf()

返回一个布尔值,表示指定的对象是否在本对象的原型链中。可以用来检查obj是否是继承自People.prototype或ClassMate.prototype

function People() {
}
function ClassMate(name,age) {
    this.name = name;
    this.age = age;
}
ClassMate.prototype = Object.create(People.prototype);
ClassMate.prototype.sex = "男"

let obj = new ClassMate("张三",18);
console.log(ClassMate.prototype.isPrototypeOf(obj))//true
console.log(People.prototype.isPrototypeOf(obj))//true

Object.prototype.propertyIsEnumerable()

判断指定属性是否可枚举。但是通过原型链继承的属性除外。如果对象没有指定的属性,则此方法返回false。


function ClassMate(name,age) {
    this.name = name;
    this.age = age;
    this.tag = ["程序猿","js","java"]
    this.say = function () {
        console.log("hello world")
    }
    this.obj = {}
}
ClassMate.prototype.sex = "男"
let obj = new ClassMate("张三",18);
console.log(obj.propertyIsEnumerable("tag"))//true
console.log(obj.propertyIsEnumerable("say"))//true
console.log(obj.propertyIsEnumerable("sex"))//false
console.log(obj.propertyIsEnumerable("id"))//false

Object.prototype.toSource()

返回字符串表示此对象的源代码形式,可以使用此字符串生成一个新的相同的对象。实测在node V9.6.1中已不可用

Object.prototype.toLocaleString()

直接调用 toString()方法。

Object.prototype.toString()

返回对象的字符串表示。


Object.prototype.unwatch()

移除对象某个属性的监听。实测在node V9.6.1中已不可用

Object.prototype.valueOf()

返回指定对象的原始值。目前并没有发下有什么卵用

Object.prototype.watch()

给对象的某个属性增加监听。实测在node V9.6.1中已不可用

Object的静态方法

Object.assign()

通过复制一个或多个对象来创建一个新的对象。浅克隆并非深度克隆。

  • 拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)??? 有待验证

    function ClassMate() {
     this.name = "张三";
     this.age = 18;
    }
    ClassMate.prototype.sex = "男"
    let classMate = new ClassMate();
    let assign = Object.assign(classMate);
    console.log(classMate)
    console.log(assign)
    console.log(assign === classMate)//true
    console.log(assign.sex)//男
    
  • 同名属性的替换

    let a = {a:"a",c : {
     c : "c"
    }}
    let b= {b:"a"}
    let assign = Object.assign(a,b);
    console.log(assign)//{ a: 'a', b: 'a' }
    console.log(assign.c === a.c)//true
    
  • Object.assign可以用来处理数组,但是会把数组视为对象。

    //Object.assign把数组视为属性名为 0、1、2 的对象,因此源数组的 0 号属性4覆盖了目标数组的 0 号属性1。
    Object.assign([1, 2, 3], [4, 5])// [4, 5, 3]
    
    • 取值函数的处理
const source = {
  get foo() { return 1 }
};
const target = {};

Object.assign(target, source)
// { foo: 1 }

Object.create()

使用指定的原型对象和属性创建一个新对象。

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = Object.create(ClassMate.prototype,{
    tags : {
        value:["程序猿","js","java"],
        enumerable :true //是否可遍历
    },
    sex :{
        value:"男"
    }
});
console.log(classMate.hasOwnProperty("tags"))
console.log(classMate.sex)
console.log(classMate)

console.log("==========")
for(let prop in classMate){
    console.log(prop)
}
/**
     true
     男
     ClassMate { tags: [ '程序猿', 'js', 'java' ] }
     ==========
     tags
 */
 //因为age不是ClassMate.prototype上的属性
 console.log(classMate.age)//undefined

Object.defineProperty()

给对象添加一个属性并指定该属性的配置。该方法允许精确添加或修改对象的属性。通过赋值来添加的普通属性会创建在属性枚举期间显示的属性(for...in 或 Object.keys 方法), 这些值可以被改变,也可以被删除。这种方法允许这些额外的细节从默认值改变。默认情况下,使用Object.defineProperty()添加的属性值是不可变的。

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();
Object.defineProperty(classMate,"tag",{
    value:["程序猿","js","java"],
    enumerable :true //是否可遍历
});
Object.defineProperty(classMate,"sex",{
    value:"男",
    writable :true //是否编辑
});

classMate.tag = []
classMate.sex = "女"
console.log(classMate)
console.log(classMate.tag)
console.log(classMate.sex)
/**
     ClassMate { name: '张三', age: 18, tag: [ '程序猿', 'js', 'java' ] }
     [ '程序猿', 'js', 'java' ]
     女
 */

Object.defineProperties()

给对象添加多个属性并分别指定它们的配置。作用和Object.defineProperty差不多,但是可以一次指定多个属性。

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();
Object.defineProperties(classMate,{
    tag :{
        value:["程序猿","js","java"],
        enumerable :true //是否可遍历
    },
    sex : {
        value:"男",
        writable :true //是否编辑
    }

});


classMate.tag = []
classMate.sex = "女"
console.log(classMate)
console.log(classMate.tag)
console.log(classMate.sex)

Object.entries()

返回给定对象自身可枚举属性的[key, value]数组。以一个数组形式方法对象

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();
Object.defineProperties(classMate,{
    tag :{
        value:["程序猿","js","java"],
        enumerable :true //是否可遍历
    },
    sex : {
        value:"男",
        writable :true //是否编辑
    }

});

let entries = Object.entries(classMate);
console.log(entries)
console.log(entries instanceof Array)

/**
 [ [ 'name', '张三' ],
 [ 'age', 18 ],
 [ 'tag', [ '程序猿', 'js', 'java' ] ] ]
 true
 */

Object.freeze()和Object.isFrozen()

冻结对象:其他代码不能删除或更改任何属性。 一个对象是冻结的是指它不可扩展,所有属性都是不可配置的,且所有数据属性(即没有getter或setter组件的访问器的属性)都是不可写的 判断对象是否已经冻结。

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();
Object.freeze(classMate)
delete classMate.name
classMate.name = '李四'
classMate.age = 81
console.log(classMate)//ClassMate { name: '张三', age: 18 }
console.log(Object.isFrozen(classMate))//true

Object.getOwnPropertyDescriptor()

返回对象指定的属性配置。该对象默认有下列四个属性

  • configurable true 当且仅当该属性描述符的类型可以被改变并且该属性可以从对应对象中删除。 默认为 false
  • enumerable true 当且仅当在枚举相应对象上的属性时该属性显现。 默认为 false
  • value 与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。 默认为 undefined.
  • writable true当且仅当与该属性相关联的值可以用assignment operator改变时。 默认为 false

  • get 作为该属性的 getter 函数,如果没有 getter 则为undefined。函数返回值将被用作属性的值。 默认为 undefined
  • set 作为属性的 setter 函数,如果没有 setter 则为undefined。函数将仅接受参数赋值给该属性的新值。 默认为 undefined
function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();Object.defineProperties(classMate,{
    tag :{
        value:["程序猿","js","java"],
        enumerable :true //是否可遍历
    },
    sex : {
        value:"男",
        writable :true //是否编辑
    }

});

console.log(Object.getOwnPropertyDescriptor(classMate,'name'))
console.log(Object.getOwnPropertyDescriptor(classMate,'tag'))

/**
     { value: '张三',
       writable: true,
       enumerable: true,
       configurable: true }
     { value: [ '程序猿', 'js', 'java' ],
       writable: false,
       enumerable: true,
       configurable: false }
 */

Object.getOwnPropertyNames()

返回一个数组,它包含了指定对象所有的可枚举或不可枚举的属性名。

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();Object.defineProperties(classMate,{
    tag :{
        value:["程序猿","js","java"],
        enumerable :true //是否可遍历
    },
    sex : {
        value:"男",
        writable :true //是否编辑
    }

});

console.log(Object.getOwnPropertyNames(classMate))
//[ 'name', 'age', 'tag', 'sex' ]

Object.keys()和Object.values()

返回一个包含所有给定对象自身可枚举属性名称的数组。 返回给定对象自身可枚举值的数组。

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();Object.defineProperties(classMate,{
    tag :{
        value:["程序猿","js","java"],
        enumerable :true //是否可遍历
    },
    sex : {
        value:"男",
        writable :true //是否编辑
    }

});

console.log(Object.values(classMate))//[ '张三', 18, [ '程序猿', 'js', 'java' ] ]
console.log(Object.keys(classMate))//[ 'name', 'age', 'tag' ]

Object.getOwnPropertySymbols()

返回一个数组,它包含了指定对象自身所有的符号属性。

Object.getPrototypeOf()和Object.setPrototypeOf()

返回指定对象的原型对象。 设置对象的原型(即内部[[Prototype]]属性)。并不改变原来对象

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();Object.defineProperties(classMate,{
    tag :{
        value:["程序猿","js","java"],
        enumerable :true //是否可遍历
    },
    sex : {
        value:"男",
        writable :true //是否编辑
    }

});
console.log(Object.getPrototypeOf(classMate))//ClassMate {}
Object.setPrototypeOf(classMate,function () {
    this.name = "李四";
    this.age = 81;
    this.say = function () {
        return 'hello'
    }
})
console.log(classMate.name)//张三
console.log(classMate.age)//18
console.log(classMate.say())//TypeError: classMate.say is not a function
console.log(Object.getPrototypeOf(classMate))//[Function]

Object.is()

比较两个值是否相同。所有 NaN 值都相等(这与==和===不同)。

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();
let object = Object.defineProperties(classMate,{
    tag :{
        value:["程序猿","js","java"],
        enumerable :true //是否可遍历
    },
    sex : {
        value:"男",
        writable :true //是否编辑
    }

});
console.log(Object.is(classMate,object))//true
console.log("" == false)//true
console.log("" === false)//false
console.log(Object.is("",false))//false

console.log(Number.NaN === NaN)//false
console.log(Number.NaN == NaN)//false
console.log(Object.is(Number.NaN ,NaN))//true

Object.isExtensible()和Object.preventExtensions()

判断对象是否可扩展。 防止对象的任何扩展。

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();
let object = Object.defineProperties(classMate,{
    tag :{
        value:["程序猿","js","java"],
        enumerable :true //是否可遍历
    },
    sex : {
        value:"男",
        writable :true //是否编辑
    }

});
if(Object.isExtensible(classMate)){
    Object.preventExtensions(classMate)
}
classMate.otherName = "zhangsan"
console.log(classMate.otherName)//undefined

Object.isSealed()和 Object.seal()

判断对象是否已经密封。 防止其他代码删除对象的属性。 Object.seal() 方法可以让一个对象密封,并返回被密封后的对象。密封对象将会阻止向对象添加新的属性,并且会将所有已有属性的可配置性(configurable)置为不可配置(false),即不可修改属性的描述或删除属性。但是可写性描述(writable)为可写(true)的属性的值仍然可以被修改。

function ClassMate() {
    this.name = "张三";
    this.age = 18;
}
let classMate = new ClassMate();Object.defineProperties(classMate,{
    tag :{
        value:["程序猿","js","java"],
        enumerable :true //是否可遍历
    },
    sex : {
        value:"男",
        writable :true //是否编辑
    }

});
Object.seal(classMate)
delete classMate.age
console.log(classMate.age)//18
classMate.sex = "女"
console.log(classMate.sex)//女
console.log(Object.isSealed(classMate))//true

参考

官方文档

本文链接:https://www.qiangshuidiyu.xin/post/js-object.html

-- EOF --

Comments