defineProperties可以定义多个属性描述符
var obj = {
// 私有属性(js里面是没有严格意义的私有属性)
_age: 18,
_eat: function() {}
}
Object.defineProperties(obj, {
name: {
configurable: true,
enumerable: true,
writable: true,
value: "why"
},
age: {
configurable: false,
enumerable: false,
get: function () {
return this._age
},
set: function (value) {
this._age = value
}
}
})
console.log(obj)
//
对象方法补充
1、获取对象的属性描述符
- getOwnPropertyDescriptor
- getOwnPropertyDescriptors
var obj = {
// 私有属性(js里面是没有严格意义的私有属性)
_age: 18,
_eat: function() {}
}
Object.defineProperties(obj, {
name: {
configurable: true,
enumerable: true,
writable: true,
value: "why"
},
age: {
configurable: false,
enumerable: false,
get: function () {
return this._age
},
set: function (value) {
this._age = value
}
}
})
// 获取某一个特定属性的属性描述符
console.log(Object.getOwnPropertyDescriptor(obj,'name'))
// 获取对象的所有属性描述符
console.log(Object.getOwnPropertyDescriptors(obj))
执行结果:
2、禁止对象扩展新属性:preventExtensions
3、禁止对象配置/删除里的属性
var obj = {
name: 'why',
age: 8
}
// 禁止对象继续添加新的属性
Object.preventExtensions(obj)
obj.height = 1.88
obj.address = "成都市"
console.log(obj)
Object.seal(obj)
delete obj.name
console.log(obj)
分别不注释Object.seal(obj)和注释Object.seal(obj)的结果
4、让属性不可以修改
var obj = {
name: 'why',
age: 8
}
// 让属性不可以修改(writable:false)
Object.freeze(obj)
obj.name = 'kobe'
console.log(obj.name)
执行结果
创建多个对象的方案
工厂模式
- 工厂模式其实是一种常见的设计模式
- 通常我们会有一个工厂方法,通过该工厂方法我们可以产生想要的对象
// 工厂模式: 工厂函数
function createPerson(name, age, height, address) {
var p = {}
p.name = name
p.age = age
p.height = height
p.address = address
p.eating = function () {
console.log(this.name + "在吃东西~")
},
p.running = function () {
console.log(this.name + "在跑步!")
}
return p
}
var p1 = createPerson('张三', 18, 1.78, '北京市')
var p2 = createPerson('李四', 23, 1.88, '成都市')
var p3 = createPerson('王麻子', 28, 1.98, '重庆市')
// 工厂模式的缺点(获取不到对象最真实的类型)
console.log(p1, p2, p3)
构造函数
// 构造函数
function person(name, age, height, address) {
this.name = name
this.age = age
this.height = height
this.address = address
this.eating = function () {
console.log(this.name + "在吃东西~")
},
this.running = function () {
console.log(this.name + "在跑步!")
}
}
var p1 = new person('张三', 18, 1.78, '北京市')
console.log(p1)
规范:构造函数的首字母一般是大写
原型的概念
// 我们每一个对象都有一个[[prototype]],这个属性可以称之为对象的原型(隐式原型)
var obj = { name: 'why'} // [[prototype]]
var info = {} // [[prototype]]
// 1、解释原型的概念和看一下原型
// 早期的ECMA是没有规范如何查看[[prototype]]
// 给对象中提供了一个属性,可以让我们查看一下这个原型对象(浏览器提供)
// __proto__
// console.log(obj.__proto__)
// console.log(info.__proto__)
var obj = { name: 'why', __proto__: {}}
// ES5之后提供的Object.getPrototypeOf
// console.log(Object.getPrototypeOf(obj))
// 2、原型有什么用
// 当我们从一个对象中获取某一个属性时,它会触发[[get]]操作
// 1、在当前对象中去查找对应的属性,如果找到就直接使用
// 2、如果没有找到,那么会沿着它的原型去查找[[prototype]]
// obj.age = 18
obj.__proto__.age = 18
console.log(obj.age)
Person构造函数原型内存图
函数原型上的属性-constructor
赋值为新的对象
function foo() {
}
// foo.prototype这个对象中有一个constructor的属性
// console.log(foo.prototype)
// console.log(Object.getOwnPropertyDescriptor(foo.prototype))
// Object.defineProperty(foo.prototype, 'constructor', {
// enumerable: true,
// configurable: true,
// writable: true,
// value: "哈哈哈哈"
// })
// console.log(foo.prototype)
// prototype.constructor = 构造函数本身
// console.log(foo.prototype.constructor) // [Function: foo]
// console.log(foo.prototype.constructor.name)
// console.log(foo.prototype.constructor.prototype.constructor.prototype.constructor)
// 2. 我们也可以添加自己的属性
// foo.prototype.name = "why"
// foo.prototype.age = 18
// foo.prototype.height = 180
// foo.prototype.eating = function () {
// }
// var f1 = new foo()
// console.log(f1.name, f1.age)
// 3.直接修改整个prototype
foo.prototype = {
// constructor: foo,
name: "why",
age: 18,
height: 180
}
var f1 = new foo()
console.log(f1.name, f1.age, f1.height)
// 真实开发中我们通过Object.defineProperty方式添加constructor
Object.defineProperty(foo.prototype, 'constructor', {
enumerable: true,
configurable: true,
writable: true,
value: foo
})
创建对象方案-原型和构造函数
function Person(name, age, height, address) {
this.name = name
this.age = age
this.height = height
this.address = address
}
Person.prototype.eating = function() {
console.log(this.name + "在吃东西~")
}
Person.prototype.running = function() {
console.log(this.name + "在跑步~")
}
var p1 = new Person('why', 18, 1.88, '北京市')
var p2 = new Person('kobe', 20, 1.98, '洛杉矶市')
p1.eating()
p2.running()