目录
3.原型链的最终指向:Object的prototype中的_proto_(null)
原型链:实例对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的。
1.关于this
2.原型的指向可以改变
实例对象stu无法访问Student原型对象中的say()方法【报错】,因为原型对象的指向改变了:
3.原型链的最终指向:Object的prototype中的_proto_(null)
4.原型指向改变,如何添加方法和访问
如果原型指向改变了,那么就应该在原型改变指向之后添加原型方法
5.一条原型链
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="div"></div>
<script>
var divObj = document.getElementById("div");
console.dir(divObj);
/* divObj.__proto__--->HTMLDivElement.prototype的__proto__--->
HTMLElement.prototype的__proto__--->Element.prototype的__proto__--->
Node.prototype的__proto__--->EventTarget.prototype的__proto__--->
Object.prototype没有__proto__,所以,Object.prototype中的__proto__是null*/
</script>
</body>
</html>
6.继承
继承:首先继承是一种关系,类(class)与类之间的关系,JS中没有类,但是可以通过构造函数模拟类,然后通过原型来实现继承。
继承也是为了数据共享,js中的继承也是为了实现数据共享
原型的另一个作用:为了实现继承,节省内存空间
6.1 通过原型实现继承(改变原型指向)
6.2 借用构造函数继承
对于6.1中的案例:
为了数据共享,改变原型指向,做到了继承——通过改变原型指向实现的继承
缺陷:因为改变原型指向的同时实现继承,直接初始化了属性,继承过来的属性的值都是固定不变的,只能重新调用对象的属性
进行重新赋值。
解决方案:继承的时候,不用改变原型的指向,直接调用父级的构造函数的方式来为属性赋值就可以了——借用构造函数,把要
继承的父级的构造函数拿过来使用一下就可以了。
借用构造函数:构造函数名字.call(当前对象,属性,属性,属性....);
解决了属性继承,值重复的问题(值不会重复了)
缺陷:父级中的方法不能继承
6.3 组合继承
组合继承:原型继承+借用构造函数继承——属性和方法都被继承了,既能解决属性问题,又能解决方法问题
6.4 拷贝继承
拷贝继承:把一个对象中的属性或者方法使用直接遍历的方式复制到另一个对象中
7.函数进阶
7.1 函数角色
7.2 函数声明和函数表达式的区别
上面两个结果都应该为f1才对,但在IE8中,两个结果分别为f2,f1
所以:函数声明如果放在if-else的语句中,在IE8中会出现问题(使用函数表达式才不会有问题)
7.3 函数中的this指向问题
- 普通函数中的this是谁?——window
- 对象.方法中的this是谁?——当前的实例对象
- 定时器方法中的this是谁?——window
- 构造函数中的this是谁?——当前的实例对象
- 原型对象方法中的this是谁?——当前的实例对象
补充:"use strict";//严格模式 (针对整个脚本文件:在脚本的首行添加;只针对函数:在函数体首行添加)
7.4 函数的不同的调用方式
7.5 函数是对象
- 对象中有__proto__原型,函数中有prototype原型
- 函数是对象,对象不一定是函数:eg.console.dir(Math);//有__proto__,但是没有prorotype——是对象不是函数
- 如果有prototype,又有__proto__,说明是函数,也是对象
- 所有的函数实际上都是Function的构造函数创建出来的实例对象