js知识点梳理-Object

116 阅读4分钟

面向对象: 在程序中使用对象描述现实中的一个事物

  • 现实事物的属性 => 对象的属性

  • 现实事物的方法 => 对象的函数

  • 现实中的所有数据都必须包含在事物中才有具体意义

面向对象和面向过程

  • 面向过程:开头->中间->结束,一直使用的开发方法

  • 面向对象:对象则包含属性和方法,如轮播对象、选项卡对象

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)
    • 原型链作用:查找属性和方法