Object(面向对象)
- 面向过程和面向对象的区别:
- 面向过程(新手):经过-开始-结束,先干什么在干什么最后干什么,一步一步的执行代码的过程。
- 面向对象:对象包含属性和方法,万物皆对象
- 为什么要面向对象:现实中所有的数据都必须包含在一个事物中才有意义。
- 面向对象的优点:
- 每个功能特地分开写——便于维护
- 所有属性和方法都保存在一个对象中,有意义又符合现实。
- 铁索连舟:一个方法触发多个方法
- 面向对象的三大特点:封装、继承、多态
- 封装:创建(3种方式)
- 直接量方式:
Var obj={
“方法名”:function(){},
}
- 构造函数方式:
Var obj=new Object();//空对象
Obj.属性名=属性值; //后面需要的属性和方法需要一个一个的添加
Obj.方法名=function(){}; //此方法一次只能创建一个对象
- 自定义构造函数方式:
function 类名(name,age,hobby) {
this.name=name;
this.age=name;
this.hobby=name;
}
var obj=new 类名(实参1,······)
强调:
- 对象的底层都是hash数组
- 获取对象中所有的东西,遍历对象for (var i in obj ){obj[i]}
- 对象方法里使用对象自己的属性名,必须写为this.属性名
- this的指向:单个元素绑定事件(这个元素),多个元素绑定事件(当前元素),
函数中出现this(谁调用,就是谁),构造函数中(当前创建的对象)
定时器中的this永远指向window
- 继承:父对象的成员(属性和方法),子对象可以直接使用
- 如何找到父对象:
- 对象名__proto__; //必须先有一个对象
- 构造函数名.prototype; // 除math、null、undefined,其他的都有构造函数名
- 面试题:两链一包(作用域链、原型链、闭包)
- 作用域链(scope chain):以EC中scope chain属性为起点,经过AO逐级引用,形的一条链式结构就称之为作用域链
作用:查找变量:优先使用局部变量,如果局部没有才找全局
(2)原型链:每个对象都有一个属性__proto__,可以一层一层的找到每个的父亲,形成了一条链式结构,就称之为原型链
作用:可以找到父辈们的成员(属性和方法),最顶层的是Object的原型,上面放着一个我们眼熟的toString,所以人人都可以使用toString(),JS中万物皆对象,除了null和undefined
- 希望保护一个可以【反复使用的局部变量】的一种词法结构,结合了两者(全局变量和局部变量)的优点
3.有了原型对象:可以一类人设置共有属性和共有方法
原型对象.属性名=属性值;//共有属性
原型对象.方法名=function(){};//公有方法
- 笔试题:
(1)判断自有还是共有
判断自有:obj.hasOwnProperty("属性名");
true->自有 false->共有或没有
判断共有:if(obj.hasOwnProperty("属性名")==false && "属性名" in obj){
console.log("共有")
}else{
console.log("没有")
}
完整版: if(obj.hasOwnProperty("属性名")){
console.log("自有")
}else{
if("属性名" in obj){
console.log("共有")
}else{
console.log("没有")
}
}
(2)删除修改自有和共有
删除自有:delete obj.属性名;
修改自有:obj.属性名=新值;
修改共有:不能直接在本地做修改!危险!在本地添加一个同名属性,根本没有修改到共有
obj.__proto__.属性名=新值;
删除共有:delete obj.__proto__.属性名;
(3)为一类对象添加共有方法:
老IE的数组没有indexOf,怎么办?
老IE的字符串没有trim,怎么办?
只要你想为一类人添加方法:
构造函数名.prototype.方法名=function(){
//自己写
}
(4)如何判断x是不是数组:千万不要使用typeof(),判断不出来的,4个方法
判断x是不是继承自Array.prototype; //Array.prototype.isPrototypeOf(x); (true->是数组)
判断x是不是由Array这个构造函数创建的 //x instanceof Array; (true->是数组)
Array.isArray(x); - ES5新提供:只要是ES5+,老IE都不支持
输出【对象的字符串】形式:
在Object的原型上保存着最原始的toString方法
原始的toString方法,默认输出 - [object Object]
固定方法:借用:if(Object.prototype.toString.apply(x)==="[object Array]"){数组}
4.实现自定义继承
(1)两个对象之间设置继承:子对象.__proto__=父对象
(2)多个对象之间设置继承:构造函数名.prototype=父对象; //创建对象使用第三种方式
注意:时机:应该在开始创建对象之前设置好关系
(三)多态:同一个函数名拥有多种形态 - 子对象觉得父对象的成员不好用,可以本地定义同名成员,覆盖了父对象的成员,比如toString不同的人使用效果不同,其实根本不是同一个toString