面向对象
一、面向对象概念
* 1、{} 字面量创建对象
* 面向对象
* 它是一种编程思想
*
* 对象
* 可以添加属性(变量)与方法(函数)的
*
*
* 面向对象的写法特点
* 1、把功能写成一个函数
* 2、函数必需在对象身上,调用的时候拿对象.方法名()
* 3、对象身上的功能可以继承例:系统本身自带的
var date=new Date();
date.getTime();
date.getHours();
var arr=new Array(1,2,3);
arr.sort();
arr.push(123);
arr.length;
二、创建对象的两种方法
var person={
name:'老王',
age:30,
sing:function(){
console.log('五环之歌');
}
};
person.height='180CM';
person.play=function(){
console.log('打飞机');
};
console.log(person);
* 2、new Object()
*
* 创建完的对象有两个特点
* 1、添加属性
* 描述对象的特征
* 属性的值为非函数的任意数据类型
* 2、添加方法
* 实现对象的一些功能
* 方法的值为函数
//第二种创建对象的方法
var person2=new Object();
person2.name='小王';
person2.age=18;
person2.play=function(){
console.log('打小飞机');
};
console.log(person2)
三、封装函数创建对象
//工厂方式
function createPerson(name,age){
var obj=new Object; //创建对象。
obj.name=name;
obj.age=age;
obj.say=function(){
console.log('我叫'+obj.name);
}
return obj; //将对象返回出去
}
var p1=createPerson('老王',30);
var p2=createPerson('小王',18);
p1.say();
p2.say();
//面向对象方式
function CreatePerson(name,age){
//var obj=new Object(); //创建对象。 //因为使用new调用的,会自动创建一个空对象,所以这里不需要自己创建空对象了。
this.name=name; //并且会自动把内部的this指向自动创建的对象
this.age=age;
this.say=function(){
console.log('我叫'+this.name+'今年'+this.age);
}
//return obj; //将对象返回出去 //以上写的内容会被放进自动创建的空对象内,并且被return出去
}
var p1=new CreatePerson('老王',30);
var p2=new CreatePerson('小王',18);
p1.say();
p2.say();
四、关于new
* new
* 一元运算符,后面只能跟函数,用来调用函数 * 调用函数的方式
* 1、new 函数名
* 没有参数的情况下用这种方式
* 2、new 函数名()
function fn(a){
if(a){
console.log(1,a);
}else{
console.log(1);
}
}
fn(); //以前调用函数的方法
new fn; //用new调用函数,不带参数
new fn(2); //用new调用函数,带参数
* 用new调用函数的执行过程
* 1、自动创建一个空对象
* 2、把函数内部的this指向创建的这个对象
* 3、在函数执行完成以后自动返回创建的那个对象,即使函数里面没有return
* 函数里有return
* 1、return的是对象
* 返回这个对象
* 2、return的是非对象
* 返回自动创建的那个对象 * 注意:
* 1、用new调用的函数,得到的永远是一个对象,不管函数有没有返回值
* 2、使用new调用函数,这个函数就是一个用来创建对象的函数(构造函数)
function fn2(){
console.log(this);
}
fn2(); //Window
new fn2; //{} this指向是创建的那个对象
var re1=fn2();
var re2=new fn2;
console.log('re1',re1); //undefined
console.log('re2',re2); //{} 返回了创建的对象
function fn3(){
//return [1,2,3]; return的是对象,
return 1; //return的是非对象
}
var re3=fn3();
var re4=new fn3;
console.log('re3',re3); //[1, 2, 3] //1
console.log('re4',re4); //[1, 2, 3] //{}
五、构造函数
* 创建并初始化对象的函数,并且需要用new来调用函数,不用new调用的话与普通的函数就没有区别
* 首字母应该大写
* Date() new Date()
* Array() new Array()
*
* 通过构造函数new出来的对象叫实例,创造对象的过程叫实例化
*
*
* 构造函数的问题
* 性能问题会造成资源浪费 ---解决方法用原型
function Person(name,age){
/*
* 1、创建一个空对象
* var obj=new Object;
* 2、把this指向创建的对象
* this=obj
*/
this.name=name;
this.age=age;
this.say=function(){
console.log('我叫'+this.name);
};
/*
* 3、函数执行完毕后,返回创建的对象
* return obj;
*/
}
var p1=new Person('老王',30); //一个实例
var p2=new Person('小王',18); //一个实例
console.log(p1.say==p2.say); //false 公用的方法变成了每一个对象特有的,这样就会造成资源浪费,解决方法---原型
var arr1=new Array(1,2,3);
var arr2=new Array(4,5,6);
console.log(arr1.push===arr2.push); //true
六、原型-prototype
* 原型 prototype
* 写法
* 构造函数名.prototype.xxx=??? 写在构造函数外面
* 概念
* 函数身上的属性,每一个函数身上都有这个属性,它的值是一个对象
* 用途
* 它身上可以放属性与方法,如果与构造函数相结合的话,通过构造函数创建的对象就会具有它身上的属性与方法
* 对象是通过构造函数创建的,那prototype就是这个对象的原型对象
* 建议把一些公用的属性或者方法都放到构造函数的原型身上(这样就可以减少资源浪费)
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.sex='男';
Person.prototype.say=function(){
console.log('我叫'+this.name);
};
var p1=new Person('老王',30); //一个实例
var p2=new Person('小王',18); //一个实例
p1.say();
p2.say();
console.log(p1.say===p2.say); //true
七、__proto__
* __proto__
* 对象身上的属性,每一个对象身上都会有这个属性。它的值也是一个对象,它的值就是它对应的构造函数的prototype的值
* 对象.__proto__===构造函数.prototype
* 作用:能够查看构造函数的原型
* 对象之所以能够继承原型身上的属性与方法,是因为每个对象身上都有一个__proto__,那__proto__的值指向了构造函数的prototype
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.sex='男';
Person.prototype.say=function(){
console.log('我叫'+this.name);
};
var p1=new Person('老王',30); //一个实例
var p2=new Person('小王',18); //一个实例
console.log(p1.__proto__===Person.prototype) //true
console.log(p1.prototype) //undefined
console.log(p1.__proto__);
八、原型链
* 原型链
* 对象与原型之间的关系(链接)
*
* 原型链查找规则
* 当我们调用一个对象身上的属性或者方法的时候,它就会有一个查找规则
* 1、首先会在自己身上去找,如果有的话就用自己的
* 2、如果没有的话,它就在该对象的__proto__下查找,因为__proto__这个属性是指向对应的构造函数身上的protytpe,把它查找的时候找的就是构造函数的原型
* 3、如果原型身上也没有的话,那它会继续往外面找,直到找到最顶层的Object身上的prototype
function Person(){
this.name='kaivon';
this.age=20;
}
Person.prototype.age=18;
Object.prototype.age=22;
var p1=new Person();
console.log(p1.age); //20 18 22
九、面向对象的写法
/*function 构造函数(){ //构造函数
this.属性=??;
}
构造函数.prototype.方法1=function(){
var This=this; //this代表的就是这个构造函数new的时候自动创建的对象
setInterval(function(){
this.方法2();
},2000)
} //原型
构造函数.prototype.方法2=function(){}
var 实例对象=new 构造函数(); //实例
实例对象.方法();*/ * 写面向对象的原则
* 1、所有的变量都做属性
* 属性需要写在构造函数里
* 2、所有的函数都要做为方法
* 方法添加到构造函数的原型
* 3、this指向,在事件或者定时器里是访问不到真正的this,需要在外面存一下this