面向对象的基本概念
一、 面向对象的概念
面向对象是一种思维方式,把解决问题的关注点放在了解决问题所需要的一些列的对象上
面向过程的概念
面向过程也是一种思维方式,把解决问题的关注点放在了解决问题的每一个详细的步骤上!
概念补充
行为 | 说明 |
---|---|
声明 | 告诉编译器/解析器有这个变量存在,这个行为是不分配内存空间的,在JavaScript中,声明一个变量的操作为:var a; |
定义 | 为变量分配内存空间,在C语言中,一般声明就包含了定义,比如:int a;,但是在JavaScript中,var a;这种形式就只是声明了。 |
初始化 | 在定义变量之后,系统为变量分配的空间内存储的值是不确定的,所以需要对这个空间进行初始化,以确保程序的安全性和确定性 |
赋值 | 赋值就是变量在分配空间之后的某个时间里,对变量的值进行的刷新操作(修改存储空间内的数据) |
数组的index of方法
indexOf在数组中查找元素,找到了返回索引,没找到返回-1
举个栗子:
var arr = [{}, [], /s/];
console.log(arr.indexOf({})); //-1
console.log({}==={}) //false 字面量就是在创建对象 两个空对象是不相等的
正确写法:
var obj = {};
var arr = [];
var reg = /s/;
var arr = [obj, arr ,reg ];
console.log(arr.indexOf(obj));
复制代码
面向对象的概念
面向对象就是一种思维方式,将解决问题的关注点放在解决问题所需要的一系列的对象上
面向过程概念
面向过程就是一种思维方式,将解决问题的关注点放在解决问题的每一个详细步骤上
面向对象和面向过程的关系
面向对象就是对面向过程的封装,有了面向对象,也不能忘记面向过程!
什么是对象,什么是js对象
万物皆对象 无序的键值对儿集合
面向对象的三大特性
- 封装 将属性和方法封装在对象内实现某些功能,在对象外部暴露一些接口,外部在使用对象的时候,只需要关心接口的使用,不需要关心对象内部的功能的具体实现
- 继承 自己没有的,别人有,拿过来用,就是继承
- 多态 父类指针指向子类的对象,js中没有多态
创建对象的方式
- 字面量
var obj = {key: value, key: value};
复制代码
- 内置构造函数
var obj = new Object();
复制代码
- 自定义构造函数
function Test(){}
var obj = new Test();
复制代码
构造函数
概念
构造也是一个函数,他是用来初始化对象的!
构造函数的特点
- 首字母大写
- 和new关键字一起使用
- 不需要手动写返回值
构造函数的执行过程
- 使用new关键字创建对象
- 调用构造函数,将构造函数内的this指向new创建出来的对象
- 使用this为对象新增成员
- 默认的返回创建出来的对象
构造函数的注意事项
- 如果手动给构造函数写返回值:
- 如果返回的是值类型,不会对返回值有任何的影响
- 如果返回的是引用类型,则返回这个引用类型的数据,之前创建的对象会被抛弃
- 如果把构造函数当做普通函数来调用,那么函数中的this就指向window,返回值和普通函数一样
原型
概念
构造函数在创建出来的时候,系统会默认的帮构造函数创建并且关联一个空的对象,这个对象就是原型
作用
在原型中的所有的成员,可以被何其关联的构造函数所创建的所有实例共享!!
原型的访问方式
- 构造函数.prototype
- 实例 .proto (不推荐使用,因为是非标准的属性)
原型的使用方式
- 利用对象的动态特性为原型对象添加成员
- 直接替换构造函数的原型属性(手动添加 constructor:函数名 属性)
注意事项
- 一般将方法放在原型当中,属性放在对象里
- 当使用对象访问属性的时候,会现在对象中进行查找,如果没有就会去原型中查找
- 替换原型的时候需要注意,替换之前创建的对象和替换之后创建的对象的原型不一致
原型链
对象都有原型,原型也是对象,所以原型也有原型,这样就形成了一个链式结构,称作原型链
属性搜索原则
- 当使用对象访问属性的时候,会现在对象自身进行查找,如果有,就直接使用
- 如果没有,就去对象的原型中进行查找,如果有,就直接使用
- 如果没有,就沿着原型链依次向上查找,直到找到,如果到null还没有找到,就会出问题
注意: 属性在设置的时候,不遵守属性搜索原则,只会在自身进行查找,如果有就修改,如果没有就新增
继承的实现方式
- 混入式继承(mix-in)for-in
- 原型继承 2.1. 利用混入的方式为原型对象新增成员,以实现继承 2.2. 直接将对象的原型替换,实现继承
- 经典继承 Object.create()
function myCreate(obj){
if(Object.create){
return Object.create(obj);
}else{
function F(){}
F.prototype = obj;
return new F();
}
}
复制代码
Object.prototype的成员
- constructor
- hasOwnProperty
- isPrototypeOf
- propertyIsEnumerable
- toString
- toLocaleString
- valueOf []==![] {}==!{}
- proto
instanceof关键字
对象 instanceof 构造函数
复制代码
判断构造函数的原型是否在对象的原型链上
Function的使用
- 没有参数创建的是空函数
- 传一个参数,这个参数会被作为函数体
- 传多个参数,前面的参数都是函数的形参名,最后一个参数为函数体
var 函数名 = new Function(arg1....argN, methodBody);
//函数名.name 为anonymous
复制代码
eval的使用
将字符串转成js代码并执行
eval(符合js语法规范的字符串)
复制代码
Function和eval的异同
都可以将字符串转换成jsdaima Function创建出来的是函数,需要手动调用才能执行 eval会直接执行
都存在如下问题:
- 执行效率问题
- 安全性问题
函数的原型链
函数也是对象,所以函数也有原型
Function是js中所有函数的构造函数,包括Function自己
完整的原型链
argumnets对象
函数内部的一个对象,是一个伪数组,在函数调用的时候,会将所有的实参依次存入这个伪数组中
- length 可以表示传入的实参的个数
- callee 指向arguments对象所在的函数
函数对象的成员
- arguments 函数内部的arguments对象
- caller 函数的调用环境,如果是在全局调用就是null,如果是在某个函数中调用,那就是那个函数
- length 形参个数
- name 函数的名
var fn = function(){};
重载 overload js中没有
//JS模拟其他语言的函数重载概念
function test(){
if(arguments.length ==1){
//功能代码
}else if(arguments.length==2){
//功能代码
}
......
}
//函数名相同,参数列表不同
var obj = {
sayHi:function(){},
sayHi:function(a){},
sayHi:function(a, b){}
}
复制代码