1、继承:父对象的成员(属性和方法),子对象可以直接使用
- 为什么继承:代码重用,节约内存
- 何时继承:只要多个子对象公用的属性和方法,都要集中定义在父对象中
2、js的面向对象是基于原型的
什么是原型:保存一类子对象共有属性和共有方法的父对象,每个对象天生就有一个原型。
1、获取原型对象:2种
- 对象名.proto
- 构造函数名.prototype
2、两链一包
- 作用域链:以函数EC的scope chain属性为起点,经过AO逐级引用,形成的一条链式结构》作用:查找变量的,带来了变量的使用规则》优先使用自己的,自己没有找全局,全局没有则报错
- 原型链:
- 每个对象都有一个._proto__的属性,可以不断的连续.找到爸爸-爷爷-祖祖...形成的一条链式结构
- 经过尝试,发现最顶层:Object.prototype是对象的原型,所有也就有了一句话:万物皆对象
- 作用:查找属性和方法,自己没有的属性和方法,可以自动顺着原型链进行查找,所以我们知道为什么人人都可以使用toString
- 闭包:保护了一个可以反复使用的局部变量的词法结构
3、获取到原型对象可以设置共有属性和共有方法
-
原型对象.属性名=属性值;//共有属性
-
原型对象.方法名=function(){};//共有方法
-
自有和共有:
- 自有:保存在对象本地的属性
- 共有:保存在父(原型)对象的属性,所有的子对象都可以使用
-
笔试题:
-
如何判断自有和共有:
-
判断自有:obj.hasOwnProperty("属性名");==》返回一个布尔值:true说明是自有,false可能是共有也可能是没有
-
判断共有:2个条件
-
不是自有:obj.hasOwnProperty("属性名")==false;
-
自动在原型链检查:"属性名" in 对象名;
-
代码:
if(obj.hasOwnProperty("属性名")==false&&"属性名" in 对象名){ //共有 }
-
-
完整版:
if(obj.hasOwnProperty("属性名")){ console.log("自有"); }else{ if("属性名" in 对象名){ console.log("共有") }else{ console.log("没有") } }
-
-
修改和删除属性:
- 修改和删除自有属性:
- 修改:obj.属性名=新值;
- 删除:delete obj.属性名;
- 修改和删除共有属性:
- 修改:原型对象.属性名=新值;
- 删除:delete 原型对象.属性名;
- 修改和删除自有属性:
-
为老IE的数组添加indexOf方法==》这道题不是固定的:为某一类设置一个方法
if(Array.prototype.indexOf===undefined){//我不希望主流浏览器也执行到这些代码,我只希望老IE执行到 Array.prototype.indexOf=function(key,starti){//indexOf的执行原理 starti===undefined&&(starti=0);//说明用户没有传入开始位置,我们就给用户设置为从下标0开始查找 for(var i=starti;i<this.length;i++){//从开始位置处,循环数组后面的每一个文字和用户输入的关键字进行匹配 if(this[i]==key){ return i;//匹配到了返回对应的下标 } } //没匹配到,返回-1 return -1; } }
-
判断一个对象是不是数组?4种方法
-
判断是不是继承自Arry.prototype==》Array.prototype.isPrototypeOf(x)
-
判断是否由构造函数Array创建的==》x instanceof Array
-
ES5创建了一个API:Array.isArray(x)==》此方法不是人人都有,而且ES5以上的东西,老IE都不支持
-
输出对象的字符串形式
在Object的prototype原型上放着原始的toString。
原始的toString,默认输出[object 构造函数名]
-
-
-
实现自定义继承
- 实现两个对象之间的继承==》子对象.proto_=父对象
- 直接批量设置继承==》构造函数名.prototype=父对象。ps:先设置好父对象,再创建子对象