面向对象三个基本特征:封装、继承、多态。
对象由属性和方法组成,属性对应变量,表示对象的基本特征,是静态的,
方法对应函数,表示对象的行为,是动态的。
字面量方式创建
// 复用率低 代码冗余
var obj = {
"name":"小明",
"age":"12",
"eat":function(){
console.log('就喜欢吃')
}
}
实例创建
// 复用率低 代码冗余 this 指向发生改变 指向当前对象
var obj = new Object()
obj.name = '张三';
obj.age = 12;
obj.eat = function(){
console.log('吃你家米了么',this.name)
}
console.log(obj)
obj.eat()
工厂模式创建
// 工厂模式 封装函数 需要返回值 return
// new typeof object 分不清
function creatObj(name,age){
var obj = new Object()
obj.name = name;
obj.age = age;
// obj.eat = function(){
// console.log('吃你家米了么',this.name)
// }
return obj;
}
creatObj('小明',12)
console.log(creatObj('小明',12))
console.log(typeof creatObj('小明',12))
creatObj('旺财',3)
console.log(typeof creatObj('旺财',3))
构造函数创建
// 函数名 函数名首字母大写
// new 干啥了? 隐式创建对象 this指向改变 隐式返回
// 增加内存
function Person(name,age){
this.name = name;
this.age = age;
this.eat = function(){
// console.log(this.name,this.age)
console.log('hahhahaha')
}
}
var xm = new Person('小明',12)
xm.eat()
var xh = new Person('小红',13)
xh.eat()
// console.log(xm.eat() == xh.eat()) ; // 值 true
console.log(xm.eat == xh.eat) ; //false
原型创建对象
//原型 每创建一个function 都有一个 prototype 方法
// console.log( Array )
// console.dir( Array ); //查看详细信息
// var arr = []
// console.log(arr.__proto__ == Array.prototype)
//原型创建
function Person(){}
// console.dir(Person)
Person.prototype.name = '李四';
Person.prototype.eat = function(){
console.log('123')
}
var xm = new Person()
// console.log(xm.name)
xm.eat()
var xh = new Person()
// console.log(xh.name)
xh.eat()
// console.log(xm.eat() == xh.eat());
console.log(xm.eat == xh.eat); //true
混合模式创建(构造+原型)
//混合模式 构造+原型
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){
console.log('完美解决所有问题')
}
var lisi = new Person('李四',28);
console.log(lisi.name)
lisi.eat()
var zhaS = new Person('张三',29);
console.log(zhaS.name)
zhaS.eat()
console.log(lisi.eat == zhaS.eat)
// 新建对象的__proto__ == prototype
动态混合模式
//动态混合 解决破坏封装的
function Person(name,age){
this.name = name;
this.age = age;
if(!(typeof this.eat == 'function')){
Person.prototype.eat = function(){
console.log('完美解决所有问题')
}
}
}
var xm = new Person('小明',12)
面向对象实例Tab切换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div>div{ display: none; border: 1px solid #f00; height: 200px; width: 200px}
.red{ background: orange}
</style>
</head>
<body>
<div id='box'>
<input type="button" value="aaa" class="red">
<input type="button" value="bbb">
<input type="button" value="ccc">
<div style="display: block">aaa</div>
<div>bbb</div>
<div>ccc</div>
</div>
<script>
//面向对象 tab切换
function Tab(id){
this.box = document.getElementById(id)
this.inp = this.box.getElementsByTagName('input')
this.div = this.box.getElementsByTagName('div')
for(var i=0;i<this.inp.length;i++){
this.inp[i].index = i
// console.log(this.inp.length)
var self = this;// 存下原来的this
this.inp[i].onclick = function(){ // 点击事件里的this 发生改变了
self.fun(this.index)
}
}
}
Tab.prototype.fun = function(x){
for(var i=0;i<this.inp.length;i++){
this.inp[i].className=''
this.div[i].style.display = 'none'
}
this.inp[x].className = 'red'
this.div[x].style.display = 'block'
}
new Tab('box');
</script>
</body>
</html>
call与apply
this
普通函数 this 指向 window
事件函数里的this 指向的 触发对象
构造函数 this 指向的 实例对象
call() apply() 改变 this 指向
call()用字符串
apply()用数组
面向对象的继承
原型链继承
// 父类
function Parent(name,age){
this.name = name;
this.age =age;
this.arr = [1,2,3]
}
Parent.prototype.money = function(){
console.log('钱')
}
//子类
function Son(){
this.play = function(){
console.log('玩耍')
}
}
// 属性 子类变不了
Son.prototype = new Parent('小白',90)
var son = new Son("小明",12)
console.log(son.name)
son.money()
son.play()
console.log(son.arr)
son.arr.push(4)
console.log(son.arr)
var son1 = new Son()
console.log(son1.arr)
// 原型继承 不能传参 引用数据类型 一个改变 会影响到其他的
对象冒充继承
// 父类
function Parent(name,age){
this.name = name;
this.age =age;
this.arr = [1,2,3]
}
Parent.prototype.eat = '大米'
Parent.prototype.money = function(){
console.log('钱')
}
//子类
function Son(name,age){
Parent.call(this,name,age)
}
var son = new Son('秦始皇',10000)
// 对象冒充继承 继承不了prototype 可以传参 引用数据不会发生改变
// son.money()
// console.log(son.eat)
console.log(son.name)
console.log(son.arr)
son.arr.push(4)
console.log(son.arr)
var son1 = new Son('武则天',8000)
console.log(son1.arr)
混合继承
function Parent(name,age){
this.name = name;
this.age =age;
this.arr = [1,2,3]
}
Parent.prototype.eat = '大米'
Parent.prototype.money = function(){
console.log('给你钱花')
}
//子类
function Son(name,age){
Parent.call(this,name,age)
}
Son.prototype = new Parent()
var son = new Son('李白',111)
console.log(son.name)
son.money()