1.call()方法
ES6之前并没有提供extends继承,我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承
call()
调用这个函数,并且修改函数运行时的this指向
fun.call(thisArg, arg1, arg2, …)
thisArg为指向的对象,arg1,arg2…为参数
<script>
function fn(x, y) {
console.log('hhhhhhhh');
console.log(this);
console.log(x+y);
}
var o = {
name: 'mary'
};
//fn.call(); call()可以调用函数
//call()可以改变这个函数的this指向
//fn.call(o);
fn.call(o, 1, 2);
</script>
2.利用父构造函数继承属性
<script>
//父构造函数
function Father(uname, age) {
this.uname = uname;
this.age = age;
}
//子构造函数
function Son(uname, age, score) {
//this指向子构造函数的实例对象
Father.call(this, uname, age);
this.score = score;
}
var son = new Son('hhhh', 18, 100);
console.log(son);
</script>
3.利用原型对象继承方法
<script>
//父构造函数
function Father(uname, age) {
this.uname = uname;
this.age = age;
}
Father.prototype.money = function() {
console.log("$2000");
}
//子构造函数
function Son(uname, age, score) {
//this指向子构造函数的实例对象
Father.call(this, uname, age);
this.score = score;
}
/*
将父构造函数的原型对象赋给子构造函数
直接赋值,如果子函数发生变化,父函数也将发生变化,不可取
*/
//Son.prototype = Father.prototype;
//子函数的原型指向父函数,constructor将被Father的constructor覆盖
//将子函数的constructor指回Son的constructor
Son.prototype = new Father();
Son.prototype.constructor = Son;
//子函数特有的方法
Son.prototype.exam = function() {
console.log('要考试了');
}
var son = new Son('hhhh', 18, 100);
console.log(son);
console.log(Father.prototype);
console.log(Son.prototype.constructor);
</script>
- 将Son构造函数的原型对象指向Father的实例对象,Son构造函数可以通过Father实例对象从Father原型对象拿到money()方法
- 若修改Son构造函数内的方法,将不会影响Father原型对象
- 由于Son原型对象指向了Father构造函数,所以Son构造函数将被Father构造函数覆盖,所以要将Son的constructor指回Son构造函数
4.类的本质
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
class Star {
}
Star.prototype.sing = function() {
console.log('hhhhh');
}
var hhh = new Star();
console.log(typeof Star);
console.log(Star.prototype.constructor);
console.log(Star.prototype);
console.log(hhh.__proto__ === Star.prototype);
</script>
</body>
</html>