# 创建属性
# 1. 实例化 Object
let person = new Object()
person.name = "john"
person.age = 18
person.sayName = function() {
console.log(`My name is ${this.name}.`)
}
# 2. 对象字面量
let person = {
name: 'john',
age: 18,
sayName: function() {
console.log(`My name is ${this.name}`)
}
}
# 3. 工厂模式
function createPerson(name, age, job) {
var o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
# 4. 构造函数模式
{
// 构造函数都以大写字母开头
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.sayName = function() {
console.log(this.name)
}
}
var person1 = new Person('john', 18, 'student')
person1.sayName()
console.log(Object.keys(person1))
console.log(Object.getOwnProperNames(person1)) // 返回所有属性
}
# 5. 原型模式
主要利用每个函数的 prototype
属性(是一个指针)指向的对象,即此函数的原型。
function Person() {
}
Person.prototype.name = 'Mike'
Person.prototype.age = 18
Person.prototype.job = 'student'
Person.prototype.friends = ['Zhang', 'Wang']
Person.prototype.sayName = function() {
console.log(this.name)
}
var person1 = new Person()
person1.sayName()
var person2 = new Person()
person2.name = 'Allen'
person2.friends.push('Li')
boboLog.hr = '实例对象属性'
person2.sayName() // 实例属性只能屏蔽原型属性,不能修改
console.log(person2.hasOwnProperty('name')) // 判断是否具有此实例属性
console.log(person1.friends) // 当属性为引用类型时,公共属性被修改
boboLog.hr
delete person2.name
console.log('person2 是否具有name实例属性:' + person2.hasOwnProperty('name'))
console.log('person2 具有属性 name in person2:' + ('name' in person2))
console.log(Object.getOwnPropertyDescriptor(person2, 'name')) // 实例读取不到原型属性的描述符
console.log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(person2), 'constructor')) // 读取原型描述符
console.log('in 是否可以读取到不可枚举属性:' + ('constructor' in person2))
console.log(person2.name) // 指回原型属性
boboLog.hr = '函数的原型对象'
console.log(Person.prototype) // 原型对象
console.log(Object.getPrototypeOf(person2)) // 通过实例 [[prototype]] 获取原型
boboLog.hr = '原型对象属性'
console.log(Object.getOwnPropertyNames(Person.prototype)) // 原型对象属性
console.log(Person.prototype.constructor.name) // 指回函数
console.log(Person.prototype.isPrototypeOf(person2)) // 判断是否为某函数原型
boboLog.hr = 'Object实例属性'
objectInstance = {}
for(let prop in objectInstance) {
console.log('不可枚举' + prop)
}
console.log('toString' in objectInstance)
console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(objectInstance)))
boboLog.hr = '探究 Object 的构造器'
console.log(typeof Object)
console.log(Object.getPrototypeOf(Object))
console.log(Object.getPrototypeOf(Object).toString())
boboLog.hr = 'Object的函数原型'
console.log(Object.prototype)
console.log(Object.prototype.__proto__)
console.log(Object.getOwnPropertyNames(Object.prototype))
boboLog.hr
console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(Object)))
console.log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Object), 'constructor'))
# 6. 组合使用构造函数模式和原型模式
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.friends = ['shell', 'court']
}
Person.prototype = {
constructor: Person,
sayName: function() {
console.log(this.name)
}
}
var person1 = new Person('Mike', 19, 'student'),
person2 = new Person('Nick', 18, 'teacher')
person1.friends.push('Wang')
console.log(person2.friends)
# 7. 动态原型模式
{
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
console.log(typeof this.sayName)
if(typeof this.sayName != "function") {
Person.prototype.sayName = function() {
console.log(this.name)
}
}
}
let person1 = new Person('Ming', 19, 'student'),
person2 = new Person('Xiao', 17, 'teacher')
person1.sayName()
person2.sayName()
}
# 8. 寄生构造函数模式
// 本质是就是工厂模式,调用时使用 new Person 模仿引用类型
{
function Person(name, age, job) {
let o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
let friend = new Person('Ming', 18, 'teacher')
friend.sayName()
}
# 9. 稳妥构造函数模式
{
function Person(name, age, job) {
let o = new Object(),
my_age = age
name = name + '_主任'
o.sayName = function() {
console.log(name)
} // 只开放了这一个接口,即构造的对象只能访问限定的数据
return o
}
let friend = Person('Ming', 11, 'student')
friend.sayName()
Object.getPrototypeOf(friend).sayAge = function() {
console.log(this.my_age)
}
friend.sayAge()
}