面向对象: 在程序中使用对象描述现实中的一个事物
-
现实事物的属性 => 对象的属性
-
现实事物的方法 => 对象的函数
-
现实中的所有数据都必须包含在事物中才有具体意义
面向对象和面向过程
-
面向过程:开头->中间->结束,一直使用的开发方法
-
面向对象:对象则包含属性和方法,如轮播对象、选项卡对象
10个引用类型都是对象(浏览器内置对象)
封装/创建/定义/声明/实例化:自定义创建对象
1.直接量法
var obj={"属性名":"属性值","方法名":function(){},}
- 属性名和方法名的""可以省略,但通常不省略,因为JSON必须添加""
- 访问对象属性和方法
obj.属性名;=== obj["属性名"];obj.方法名()=== obj["方法名"]();
- 访问到不存在的属性:undefined(下标越界)
- 可在后续随时添加想要的东西
obj.新属性名="属性值";
this 在当前对象的方法内,指向的当前调用方法对象
- 单个元素绑定事件 this -> 单个元素
- 多个元素绑定事件 this -> 当前元素
- 函数 this -> 当前调用函数的对象
- 构造函数中 this -> 当前创建的对象
- 定时器 this -> timer
2.预定义构造函数法
var obj=new Object();//创建一个空对象obj.属性名=属性值;obj.方法名=function(){};
3.自定义构造函数法
- 创建一个构造函数
function 类名(形参,...){this.属性名=形参1;...} - 反复调用构造函数,创建出多个对象
var x=new 类名(实参,...); - 遍历
for(var i in obj){obj[i]} - 优点
- 所有操作都包含在一个对象中
- 维护效率高
- 一个方法调用,触发了很多操作
继承
- 父元素的成员(属性和方法),子对象可以直接使用
- 为什么继承:代码重用,节约内存空间
- 何时继承:只要多个子元素公用的属性和【方法】,都应集中在父元素中
- js的面向对象是基于原型(父元素)的
原型
保存着一类子对象共有属性和共有方法的原型对象(父元素)
- 如何找到原型对象
对象名.__proto__至少要创建一个对象才能使用本方法构造函数名.prototype
new 构造函数(Object/RegExp/Date/Function/String/Number)
- 在原型对象中添加共有属性和共有方法
原型对象.属性名=属性值;原型对象.方法名=function(){}- 每个对象都有一个
.__proto__的属性指向着自己的原型 - 每个构造函数都有一个
.prototype属性指向自己的原型
- 原型链: 自己没有的属性和方法,可以顺着原型链向上找,直到最顶层(Object.prototype)
- 作用:查找属性和方法
- 自有和共有
- 自有:保存在对象本地
- 共有:保存在原型对象中,子对象都可以直接使用
常见问题
1.判断一个属性是自有还是共有
自有 obj.hasOwenPrototype("属性名");
- true -> 自有
- false -> 可能共有,也可能没有
共有: 2个条件
obj.hasOwenPrototype("属性名")==false;//判断不是自己"属性名"in obj;//in关键字会查找自己的原型
//判断自有、共有
if(obj.hasOwenPrototype("属性名")){
console.log("自有");
}else{
if(obj.hasOwenPrototype("属性名")=false&&"属性名" in obj){
console.log("共有");
}ekse{
console.log("没有");
}
}
2.修改/删除属性
自有
- 修改
obj.属性名=新值; - 删除 `delete obj.属性名;
共有: 找到原型再做操作
- 修改:不要在本地做操作,会导致在本地添加上一个同名属性,优先使用自己的,但没有修改原型
- 删除:不要再本地做操作,本地操作无效果
3.为一类人添加方法
//为老IE数组添加indexOf方法
if(Array.prototype.indexOf===undefined){
Array.prototype.indexOf=function(key,starti){
starti===undefined&&(starti=0);//设置默认值
for(var i=starti;i<this.length;i++){
if(this[i]==key){
return i;
}
}
return -1;
}
}
4.判断x是否是数组
-
方法1 判断当前对象是否是继承自Array.prototype
Array.prototype.isPrototypeOf(x);也可以判断其他类型- true:数组
-
方法2 判断当前对象是否是由此构造函数创建
x instanceof Array;也可判断其他类型- true:数组
-
方法3
Array.isArray(x);只有数组有这个方法- true:数组
-
方法4 多态
- 在Object的prototype中保存着最原始的toString方法
- 原始的toString输出的结果:[object 构造函数名]
if(Object.prototype.toString.apply(arr)==="[object Array]"){
数组
}
多态: 子对象觉得父对象提供的方法不好用,可在本地定义一个同名成员,有限使用离自己更近的方法(同一函数名,但不是同一个方法)
5.如何设置自定义继承
- 设置单个对象的继承:
obj.__proto__=新对象; - 设置多个对象的继承:(创建对象前要设置好父对象)
构造函数名.prototype=新对象;
两链一包
- 闭包 保护一个可以【反复使用的局部变量】的一种词法结构
- 作用:结合全局和局部的优点
- 作用域链 以EC中的scope chain属性为起点,经过AO逐级隐痛,形成的一条链式结构
- 作用域链:查找变量
- 原型链 自己没有的属性和方法,可以顺着原型链向上找至最顶层(Object.prototype)
- 原型链作用:查找属性和方法