1. 先有构造函数,再有的实例对象
2. 构造函数里面有一个原型对象
3. 原型对象里面的构造器指向对应的构造函数
4. 实例对象里面的原型指向构造函数里面的原型对象
原型链:是一种关系,实例对象和原型对象之间的关系,通过__proto __来联系的,构造函数本身与实例对象没什么联系
构造函数里面的原型对象里面的原型__proto__指向的是objct,,objct的原型为null
例如:
var divObj = document.getElementById("dv")
console.dir(divObj);
var divObj = document.getElementById("dv")
console.dir(divObj);
divObj.__proto__---->HTMLDivElement.prototype的__proto__----->
HTMLDivElement.prototype的__proto__----->Element.prototype的
__proto__----->Node.prototype的__proto__-------->
eventTarget.prototype的__proto__---->Object.prototype没有__proto__,
所以Object.prototype中的__proto__为null
this对象
构造函数中的this是实例对象
严格模式:
"use strict";
function f1 () {
console.log(this) ;window
}
f1(); //当加上严格模式后f1()调用结果为undefined,Window.f1()才对
不加上严格模式,不用加Window
原型对象方法中的this也是实例对象
原型的指向改变
当原型对象prototype里面的指向改变了,那么原型__proto__指向也改变了
这里的原型对象的指向相当于C语言中的指针
先改变原型对象的指向,再添加方法,才能访问当前的方法
这里就相当于我告诉你钱在我这让你来拿,但是你来的途中,我说钱不在我这,所以你在我这拿不到钱,而如果先把钱移动的位置告诉你,你就可以直接拿到钱,是一个道理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
function Person (age) {
this.age = age;
}
Person.prototype.study = function () {
console.log("学习很重要");
}
function Zhu () {
}
Zhu.prototype = new Person(10);
Zhu.prototype.eat = function () {//指向改变后,再给一个新的原型
console.log("猪只知道吃");
}
var zhu = new Zhu();
// var stu = new Person(10);
zhu.study();
zhu.eat();
</script>
</body>
</html>
继承
真正的面向对象语言存在类(class)(特殊的数据类型),js没有类的概念,不是面向对象的语言,所以js没有类,但是js可以模拟面向对象的思想编程,js中会通过构造函数来模拟类的概念
继承:首先继承是一种关系,类与类之间的关系,js中没有类,但是通过构造函数模拟类,然后通过原型来实现继承
继承也是为了数据共享,js中的继承也是为了实现数据共享
原型作用之一:实现数据共享,节省空间
原型作用之二:为了实现继承
1,通过构造函数原型对象来继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
//通过原型继承 ,虽然能继承,但是都是一样的属性与值
function Person (name,age,sex) {
this.name = name ;
this.age = age ;
this.sex = sex ;
}
Person.prototype.study = function () {
console.log("学习");
}
function Stu (score) {
// this.name = name ;
// this.age = age ;
// this.sex = sex ;
this.score = score;
}
Stu.prototype = new Person("张",17,"男"); //使学生的指向改变成人,那么人里面的属性和方法都能共享
Stu.prototype.study1 = function () {
console.log("学习");
}
var stu = new Stu(100);
var stu1 = new Stu(100);
var stu2 = new Stu(100);
stu.study();
stu1.study();
stu2.study();
console.log(stu.name,stu.sex,stu.age,stu.score);
console.log(stu1.name,stu1.sex,stu1.age,stu1.score);
console.log(stu1.name,stu1.sex,stu1.age,stu1.score);
</script>
</body>
</html>
这个继承的缺点是所有继承的属性,方法都一样
那么如何解决这种问题呢,来后接下来讲一讲下面这种继承
2,通过构造函数的借用继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
//借用构造函数继承 :构造函数名字.call(当前对象,属性),解决了属性继承,并且值不重复,但是方法不能继承
function Person (name,age,sex) {
this.name = name ;
this.age = age ;
this.sex = sex ;
}
Person.prototype.study = function () {
console.log("学习");
}
function Stu (name,age,sex,score) {
// this.name = name ;
// this.age = age ;
// this.sex = sex ;
Person.call(this,name,age,sex,score);//相当于调用Person对象
this.score = score;
}
// Stu.prototype = new Person("张",17,"男");
Stu.prototype.study1 = function () {
console.log("学习");
}
// stu.name = "张";
// stu.sex = "男"; 在这里重新赋值就可以了,但是太多,而且这样就没有传值的必要性了
// stu.age = "19";
// var stu1 = new Stu(1);
var stu1 = new Stu("张1","男1",119,1100);
// stu1.name = "张1";
// stu1.sex = "男1";
// stu1.age = "20";
// var stu2 = new Stu(1001);
var stu2 = new Stu("张2","男2",129,1200);
// stu2.name = "张2";
// stu2.sex = "男2";
// stu2.age = "21";
// var stu3 = new Stu(1002);
var stu3 = new Stu("张3","男3",139,1300);
// stu3.name = "张3";
// stu3.sex = "男3";
// stu3.age = "22";
console.log(stu1.name,stu1.sex,stu1.age,stu1.score);
console.log(stu2.name,stu2.sex,stu2.age,stu2.score);
console.log(stu3.name,stu3.sex,stu3.age,stu3.score);
stu3.study(); //报错,方法不能继承
</script>
</body>
</html>
这种方法虽然解决了属性值不用,但是缺陷在于其方法不能继承,调用方法,会报错 ,那么为了解决不报错问题,接下来引入
3.组合继承(原型与借用一起使用)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
function Person (name,age,sex) {
this.name = name ;
this.age = age ;
this.sex = sex ;
}
Person.prototype.study = function () {
console.log("学习");
}
function Stu (name,age,sex,score) {
Person.call(this,name,age,sex,score);//相当于调用Person对象
this.score = score;
}
Stu.prototype = new Person(); //不传值
Stu.prototype.study1 = function () {
console.log("学习");
}
var stu1 = new Stu("张1","男1",119,1100);
var stu2 = new Stu("张2","男2",129,1200);
var stu3 = new Stu("张3","男3",139,1300);
console.log(stu1.name,stu1.sex,stu1.age,stu1.score);
stu1.study();
console.log(stu2.name,stu2.sex,stu2.age,stu2.score);
stu2.study();
console.log(stu3.name,stu3.sex,stu3.age,stu3.score);
stu3.study();
</script>
</body>
</html>
后面还有继承的方法,明日再来总结