在js中一个Object可能是一组数据,一个组件,一个页面,一个项目,创建一个Object之后,是有一些内置的原生方法可以使用来管理整个Object里的所有内容的。
Object的各项原生方法:
js中直接使用Object.xxx来调用内置的方法,其中包括了对内部数据的增删改查、可遍历,获取状态,修改状态等进行配置,以及对这些配置进行限制和获取这些配置项的方法。
var obj = {
name: 'obj_000',
type: 'object',
local: 'first',
}
// 数据属性描述符,value,writable, configurable, enumerable属性
Object.defineProperty(obj, "index", {})
// 存取属性描述符, 不可使用value,writable属性,增加get(获取),set(编辑)两个函数
Object.defineProperty(obj, "index", {
get: function() {
},
set: function (value) {
}
})
// 批量设置属性描述符, 每个属性一个Object来配置
Object.defineProperties(obj, {
name: {},
type: {},
local: {}
})
// 禁止对象继续添加新的属性
Object.preventExtensions(obj)
// 让属性不可以修改(writable: false)
Object.freeze(obj)
// 禁止对象配置和删除里面的属性
Object.seal(obj)
// 获取对象的属性描述符
Object.getOwnPropertyDescriptors(obj)
Object.getOwnPropertyDescriptors(obj, "name")
// 获取对象原型
Object.getPrototypeOf(obj)
各项原生方法的配置项:
配置Object中方法分为:批量配置和单个配置,也可以分为:数据属性描述和存取属性描述,可以根据不同的场景需求来使用。
1、数据属性描述符
var obj = {
name: 'obj_000',
type: 'object',
local: 'first',
}
// defineProperty方法会修改传入的对象
Object.defineProperty(obj, "index", {
value: "1" , // 默认值undefined,设置属性值
configurable: true, // 默认值false,是否可以删除
enumerable: true, // 默认值false,是否是可以遍历
writable: true // 默认值false,否是可以赋值
})
// 1、configurable设置false则无法删除
delete obj.index;
console.log(obj);
// 2、enumerable设置false则遍历不出来index
for (const k in obj) {
console.log(obj[k]);
}
// 3、writable设置为false则无法给index赋值或修改数据
obj.index = '广州'
console.log(obj.index);
2、存取属性描述符
var obj = {
name: 'obj_000',
type: 'object',
local: 'first',
index: '0',
index1: "1"
}
Object.defineProperty(obj, "index1", {
enumerable: true, // 默认值false,是否是可以遍历
configurable: true, // 默认值false,是否可以删除
get: function() { // 获取该属性
return this.index
},
set: function(value) { // 修改该属性
this.index = value
foo()
// vue2数据响应的方法,当index1被修改时index的数据也会做相同的变更
}
})
obj.index1 = "3"
console.log(obj);
function foo() {
console.log('响应了index的数据!');
}
3、批量设置属性描述符
var obj = {
name: 'obj_000',
type: 'object',
local: 'first',
_index: '0'
}
Object.defineProperties(obj, {
name: {
configurable: true, // 默认值false,是否可以删除
enumerable: true, // 默认值false,是否是可以遍历},
},
type: {
configurable: false, // 默认值false,是否可以删除
enumerable: false, // 默认值false,是否是可以遍历
writable: false // 默认值false,否是可以赋值
},
local: {
configurable: true, // 默认值false,是否可以删除
enumerable: true, // 默认值false,是否是可以遍历},
},
index: {
configurable: true,
enumerable: true,
get: function() {
return this._index
},
set: function(value) {
this._index = value
}
}
})
obj.type = "object1"
obj.name = "obj_001"
console.log("1、type:",obj.type, '2、name:', obj.name);
// 1、type: object 2、name: obj_001
for (const k in obj) {
console.log(obj[k]);
// obj_001
// first
// 0
// 0
}
obj.index = 1
console.log(obj.index, obj._index); // 1 1
3、设置和调用Object原型链
function test(name, local) {
this.name = name
this.local = local
}
test.prototype.thing = function () {
console.log(this.name+ "住在" + this.local);
}
var test1 = new test("张三", "昆明")
var test2 = new test("李四", "成都")
test1.thing() // 张三住在昆明
test2.thing() // 李四住在成都
console.log(test1);
3、原型链继承的封装
function Parent() {
this.isName = 'Parent'
}
Parent.prototype.thing = function (value) {
console.log(this.isName +"正在"+ value);
}
function inheritPrototype(ParentData, SubData) {
function Fn() {}
Fn.prototype = ParentData.prototype
SubData.prototype = new Fn
// SubData.prototype = Object.create(ParentData.prototype)
Object.defineProperty(SubData.prototype, "constructor", {
enumerable: false,
configurable: true,
writable: true,
value: SubData
})
}
function Sub() {
this.isName = 'Sub'
}
inheritPrototype(Parent, Sub)
var s1 = new Parent
var s2 = new Sub
s1.thing('跑步') // Parent正在跑步
s2.thing('爬山') // Sub正在爬山
4、原型链属性判断的方法
var obj = {
egg: "3",
}
var p1 = Object.create(obj, {
address: {
value: "sz"
}
})
function foo() {
}
var p2 = new foo
// hasOwnProperty方法判断是否是自己原型上的属性
console.log(p1.hasOwnProperty("address")) // true
console.log(p1.hasOwnProperty("egg")) // false
// in 操作符: 不管在当前对象还是原型中返回的都是true
console.log("address" in p1) // true
console.log("egg" in p1) // true
// 返回整个原型对象
console.log(Object.getOwnPropertyDescriptors(foo.prototype))
// 构造函数的原型是否出现在实例对象的原型链上
console.log(p2 instanceof foo) // true
console.log(p1 instanceof foo) // false
5、继承内置类和混入
// 继承内置类
class HYArray extends Array {
firstItem() {
return this[0]
}
lastItem() {
return this[this.length-1]
}
}
var arr = new HYArray(1, 2, 3)
console.log(arr.firstItem())
console.log(arr.lastItem())
// 混入
class Person {
}
function mixinRunner(BaseClass) {
class NewClass extends BaseClass {
running() {
console.log("running~")
}
}
return NewClass
}
function mixinEater(BaseClass) {
return class extends BaseClass {
eating() {
console.log("eating~")
}
}
}
// 在JS中类只能有一个父类: 单继承
class Student extends Person {
}
var NewStudent = mixinEater(mixinRunner(Student))
var ns = new NewStudent()
ns.running()
ns.eating()