面向对象

一.面向对象创建方式

对象—属性、方法

1.普通方式

    var obj=new Object()
    //添加对象属性
    obj.a=12
    obj.b="hello"
    //添加对象方法
    obj.m1=function(){alert("m1...")}
    obj.m2=function(){alert("m1...")}
    console.log(obj)

            var obj=new Object()
    //添加对象属性
    obj.a=12
    obj.b="hello"
    //添加对象方法
    obj.m1=function(){alert("m1..."+this.a)}
    obj.m2=function(){alert("m1...")}
    console.log(obj)
    //对象的调用
    console.log(obj.a)
    console.log(obj.m1)  

    var obj=new Object()
    //添加对象属性
    obj.a=12
    obj.b="hello"
    //添加对象方法
    obj.m1=function(){
        console.log(this)
        alert("m1..."+this.a)
    }
    obj.m2=function(){alert("m1...")}
    console.log(obj)
    //对象的调用
    obj.m1()

2.直接量方式

var obj1={
a:12,
b:“hello”,
m1:function(){alert(“m1…”+this.a)},
m2:function(){alert(“m1…”)}
}
console.log(obj1)

3.函数对象方法

function f1(a,b){return a+b}
转换
var f1=new Function('a','b',"alert(a+b)")
f1()

var obj=new Function('this.a=12';
                      'this.b="hello";
                      this.m1=function(){alert("m1..")}';
                      this.m2=function(){alert("m2..")}
                      )

    var obj=new Function('this.a=12;this.b="hello";this.m1=function(){alert("m1..")};this.m2=function(){alert("m2..")}')
    //调用
    var o1=new obj()
    console.log(o1.a)
    o1.m2()

4.构造函数方式

 function Person(){
        this.name = "zs"
        this.age = 23
        this.say = function(){alert("hello")}
        this.eat = function(){alert("ganguoji...")}
    }
    //创建实例
    var hyw1 = new Person()
    console.log(hyw1.age)
    console.log(hyw1.eat)
    var hyw2 = new Person()
    console.log(hyw2.age)
    console.log(hyw2.eat)

5.原型方式创建

   function Person(){
    Person.prototype.name="zs"
    Person.protype.age=23
    Person.prototype.say=function(){
        alert("hello...")
    }
    Person.prototype.eat=function(){
        alert("ganguoji")
    }
}
//创建实例
var p1=new Person()
p1.age
p1.eat()

二、对象的属性设置–defineProperty

1、Object.getOwnPropertyDescriptor() 获取对象属性

var Person={
name:“zs”
}
var des=Object.getOwnPropertyDescriptor(Person,“name”)
console.log(des.value) //zs
console.log(des.configurable) //true
console.log(des.writable) //true
console.log(des.enumerable) //true

2、对象的数据属性

value 属性的属性值
configurable 能否删除属性的值
writable 能否修改属性的值
enumerable 能否遍历(枚举)属性的值

(0)var Person={}
Object.defineProperty(Person,“name”,{value:“zs”})
var des=Object.getOwnPropertyDescriptor(Person,“name”)
console.log(des.value) //zs
console.log(des.configurable) //false
console.log(des.writable) //false
console.log(des.enumerable) //false

(1) var Person={}
Object.defineProperty(Person,“name”,{value:“zs”,writable:false})
console.log(Person.name) //zs
Person.name=“ls”
console.log(Person.name) //zs

(2)var Person={}
Object.defineProperty(Person,“name”,{value:“zs”,writable:false})
Object.defineProperty(Person,“age”,{value:“23”,enumerable:true})
Object.keys(Person)

(3)var Person={}
Object.defineProperty(Person,“name”,{value:“zs”,configurable:true})
Object.defineProperty(Person,“age”,{value:23,configurable:false})
delete Person.name
console.log(Person.name) //undefined
delete Person.age
console.log(Person.age) //23

3、对象的访问属性

get :在读取属性时调用的函数
set :在写入属性时调用的函数

var Person={
name:“zs”
Object.defineProperty(Person,“age”,{value:23,get:function(){
console.log(“get…”)
}})
}
Person.age

4、MVVM vue实现双向绑定

var obj={}
Object.defineProperty(obj,“name”,{
set:function(val){
document.getElementById(“id02”).innerHTML=val
}
})
document.getElementById(“id01”).addEventListener(“keyup”,function(event){
esrc=event.target
obj.name=esrc.value
})

三、继承

1、约定

  function Person(){
      var name="zs"           //私有的基本属性
      var friends=["ls","ww"] //私有的引用属性
      function f1(){}         //私有的函数
}  

 function Person(){
      this.name="zs"           //实例的基本属性
      this.friends=["ls","ww"] //实例的引用属性
      this.f1=function(){}     //实例的函数
}  
 function Person(){}
      Person.prototype.name="zs"           //原型的基本属性
      Person.prototype.friends=["ls","ww"] //原型的引用属性
      Person.prototype.f1=function(){}     //原型的函数

2、原型链继承

   function Cat(){}
   Cat.prototype=new Animal()
   创建一个对象,Animal,构造函数+原型
   name  引用类型  方法say  eat
   function Animal(){
this.name=name
this.friends=["A","B"]
this.say=function(){
    console.log("say...")
}

}
Animal.prototype.eat=function(){
console.log(“eat…”)
}
//继承
function Cat(){}
Cat.prototype=new Animal()
Cat.prototype.name=“Cat”
//实例
var c1=new Cat()
console.log(c1.name)
c1.name=“jfcat”
console.log(c1.friends)
c1.friends.push(“jfcat01”)
var c2=new Cat()
console.log(c2.friends)
总结:
核心:Cat.prototype=new Animal() 拿父类实例充当子类原型对象
原型链查找顺序:先在实例内查找,再找实例对象的构造函数,再找实例对象的原型,再找父类的构造函数,再找父类的原型
优点:简单易于实现
缺点:原型的引用类型属性是所有实例共享的
创建子实例时,无法向父类构造函数传参

3、原型链原理

    function Animal(){}
    Animal.prototype.name="animal"
    Animal.prototype.say=function(){console.log("hello")}
    console.log(Animal)
    console.log(typeof(Animal.prototype))     //object
    console.log(Animal.prototype.constructor) //Animal()

    (1)每个函数都有一个显示的"prototype"熟悉,该属性指向原型对象
    (2)原型对象中的"constructor"属性,指向函数本身
    (3)new创建的对象没有原型属性
    // var a1=new Animal()
    // console.log(a1)
    // console.log(a1.__proto__)
    // console.log(a1.prototype)  //undefined
    (4)每个对象都有一个"__proto__"内部隐藏属性
       指向它所对应的原型对象(chrome--[[]] firefox--<>)
    (5)原型链是利用原型上一个引用类型继承另一个引用类型的原型方法
       原型链正是基于"__proto__"才得以形成
    (6)console.log(Object.prototype.__proto__==null)  //原型链结束

4、(借用)构造函数继承

    Animal.call(this,arg)  //继承
    function Animal(val){
        this.name=val
        this.friends=["a","b"]
        this.say=function(){
            console.log("say...")
        }
    }
    function Person(arg){
        Animal.call(this,arg)
    }
    var p1=new Person("zs")
    console.log(p1.name)
    p1.friends.push("ww")
    var p2=new Person("ls")
    console.log(p2.name)
    console.log(p2.friends)

总结:
核心:借用父类的构造函数来增强子类的实例,完全没用到原型
优点:
1、解决了子类实例共享父类引用属性的问题
2、创建子类时可以向父类构造函数传参
缺点:
1、无法实现函数的复用,每个子类实例都持有一个新的function函数实例,消耗内存

5、组合继承(构造函数+原型链)

    function Animal(val){
        this.name=val
        this.friends=["a","b"]
    }
    Animal.prototype.say=function(){
        console.log("say...")
    }
    function Person(){
        Animal.call(this,arg)  //继承父类基本属性,并保留了传参的有点
    }
    Person.prototype=new Animal()   //继承了父类函数,实现函数复用
    var p1=new Person("zs")
    console.log(p1.name)
    p1.friends.push("ww")
    var p2=new Person("ls")
    console.log(p2.name)
    console.log(p2.friends)
    console.log(p1.say==p2.say)

总结:
核心:把实例函数都放在原型对象上,以实现函数复用,并保留构造函数的优点
优点:
1、不存在引用类型属性共享问题
2、可传参
3、函数可复用
缺点:
1、因为父类的构造函数被调用了两次,生成了两份,浪费内存

6、原型式继承

    function Beget(obj){  //生孩子函数
        function F(){}
            F.prototype=obj
            return new F()
    }
    function Animal(){
        this.name="Animal"
        this.friends=["ls","ww"]
    }
    var Person=new Animal()
    var p1=Beget(Person)
    console.log(p1.name)   //Animal
    p1.friends.push("zl")
    console.log(p1.friends)  //['ls', 'ww', 'zl']
    var p2=Beget(Person)
    console.log(p2.name)   //Animal
    console.log(p2.friends)  //['ls', 'ww', 'zl']

核心:用生孩子函数得到一个"纯洁"的(没有实例属性)的新对象

7、寄生式继承

     function Beget(obj){  //生孩子函数
        function F(){}
            F.prototype=obj
            return new F()
    }
    function Animal(){
        this.name="Animal"
        this.friends=["ls","ww"]
    }
    function getSubObject(obj){
        var clone=Beget(obj)
        clone.age=23
        return clone
    }
    var Person=getSubObject(new Animal())
    console.log(Person.name)   //Animal
    console.log(Person.age)    //23

8、寄生组合式继承 —最佳

    function Beget(obj){  //生孩子函数
        function F(){}
            F.prototype=obj
            return new F()
    }
    function Animal(){
        this.name="Animal"
        this.friends=["ls","ww"]
    }
    Animal.prototype.say=function(){
        console.log("say...")
    }
    function Person(){
        Animal.call(this)
    }
    //核心代码 --切掉了原型对象上多余的那份父类实例属性
    var p=Beget(Animal.prototype)
    p.constructor=Person
    Person.prototype=p

    var p1=new Person()
    console.log(p1.name)    //Animal
    console.log(p1.friends) //["ls","ww"]

优点:完美
缺点:没有

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秃头程序员-疯子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值