面向对象的程序设计

属性类型

数据属性
[[Configurable]]:是否能通过delete删除属性,默认为true
[[Enumberable]]:是否能通过for-in返回属性,默认为true
[[Writable]]:能否修改属性的值,默认为true
[[Value]]:数据
改变上述属性
Object.defineProperty()
var person = {}
Object.defineProperty(person,"name",{
    writable: false,   //不能重写
    value: "123",
    configurable: false,  //以后再也不可配置
    enumerable: true
})
console.log(person.name)    //123
person.name = "456"
console.log(person.name)    //123
访问属性
[[Configurable]]:是否能通过delete删除属性,默认为true
[[Enumberable]]:是否能通过for-in返回属性,默认为true
[[Get]]:读取属性的时候调用的函数
[[Set]]:写入属性的时候调用的函数
var book = {
    year: 2017,
    edition: 1
}
Object.defineProperty(book,"month",{   //对month进行访问
    get: function(){
        return "123"
    },
    set: function(newValue){
        if(newValue>2017){
            this.year = newValue        
        }
    }
})
book.month = 2018     //调用set
console.log(book.year)
console.log(book.month)    //get方法返回123
访问多个属性
var book = {
    year: 2017,
    edition: 1
}
Object.defineProperties(book,{
    edition:{
        writeable:true,
        value: 2015
    },
    month:{
        get: function(){
            return "123"
        },
        set: function(newValue){
            if(newValue>2017){
                this.year = newValue
            }
        }
    }
})
book.month = 2018
console.log(book.year)   //2018
console.log(book.month)  // 123
console.log(book.edition)  //2015
获得属性 Object.getOwnPropertyDescriptor()
var descriptor = Object.getOwnPropertyDescriptor(book,"year")
console.log(descriptor) 

创建对象

最合适的方法–构造函数模式和原型模式
function Person(name , age){
    this.name = name
    this.age = age
}
Person.prototype = {
    constructor: Person,
    sayName: function(){
        console.log(this.name)
    }
} 
var john = new Person("john")
john.sayName()   //john   
此类方法属性不共享,方法共享
其他要点
1.可将构造函数当普通函数用,原型中不行,只能在构造函数模式中
function Person(name , age){
    this.name = name
    this.age = age
    sayName = function(){
        console.log(this.name)
    }
}
Person("john")
window.sayName()   //john
2.内存区问题 sayName()在同一内存区
function Person(name , age){
    this.name = name
    this.age = age
}
Person.prototype = {
    constructor: Person,
    sayName: function(){
        console.log(this.name)
    }
} 
var person1 = new Person("john")
var person2 = new Person("john2")
console.log(person1.sayName == person2.sayName) 
另一种情况 sayName在不同内存区(没有this是true)
function Person(name , age){
    this.name = name
    this.age = age
    this.sayName = function(){
        console.log(this.name)
    }
}
var person1 = new Person("john")
var person2 = new Person("john2")
console.log(person1.sayName == person2.sayName)  //false

原型–>我的理解是一个实例,所有其他实例的父类

isPrototypeOf()验证是否为某原型的实例
Person.prototype.isPrototypeOf(person1) //true
hasOwnProperty()检测属性是否存在于实例中
person1.hasOwnProperty(“name”)

function Person(){}
Person.prototype = {
    name : "name",
    age : "age",
    sayName: function(){
        console.log(this.name)
    }
} 
var person1 = new Person()
console.log(person1.hasOwnProperty("name")) //false
person1.name = "123"
console.log(person1.hasOwnProperty("name")) //true

原型与继承

每个构造函数都有原型,每个原型都有指针指向构造函数,每个实例都有指向原型的指针
function Animal(){}
Animal.prototype = {
    constructor: Animal
    //__proto__  
}
function Dog(){}
Dog.prototype ={
    constructor: Dog  
    //__proto__  
}

Dog.prototype = new Animal() //继承
let dog1 = new Dog()
console.log(dog1)
//Dog.__proto__ = Animal
//Animal.__proto__ = Object
每个实例中都有proto指向new的类,若没有则指向本身
原型与实例的关系
instance intanceof Object
Object.prototype.isPrototypeOf(intance)

最常用的继承模式–组合继承

function Super(){
    this.property = true
}
Super.prototype.getSuperProperty = function(){
        return this.property    
}
function Sub(){
    this.subProperty = false
    Super.call(this)
}
Sub.prototype = new Super()
Sub.prototype.getSubProperty = function(){    
    return this.subProperty    
}
let inte = new Sub()
console.log(inte.getSuperProperty())
console.log(inte.getSubProperty())
注意子类不能使用字面量的方法如下所示,它会重写了原型链,父类可以用字面量写法
Sub.prototype = {}

我最常用的方法–野路子

function Super(){
    this.property = true
}
Super.prototype = {
    constructor: Super,
    getSuperProperty: function(){
        return this.property
    }        
}
function Sub(){
    this.subProperty = false
    Super.call(this)
}
Sub.prototype = {
    constructor: Sub,
    getSubProperty: function(){
        return this.subProperty
    },
    __proto__: Super.prototype
}
let inte = new Sub()
console.log(inte.getSuperProperty())  /true
console.log(inte.getSubProperty())    /false

面向对象的程序设计
https://zhangfuli.github.io/2017/09/25/面向对象的程序设计/
作者
张富利
发布于
2017年9月25日
许可协议