在ES6之前没有类的概念,利用构造函数与原型对象实现面向对象编程。
构造函数
属性和方法。
静态成员:属性和方法是通过构造函数添加,调用时也必须使用构造函数调用,不能使用实例化对象调用。
实例成员:属性和方法是在内部通过this添加,调用时必须使用实例化对象调用,不能使用构造函数调用。
原型对象
prototype:每个构造函数都有一个原型对象。
将方法直接存储在构造函数中,浪费空间(因为每个实例化对象都需要重新申请空间存放方法),可以将其存储到构造函数的原型对象上。
_proto _:每个对象都有对象原型,它指向该对象的原型对象。
constructor:指向原型对象的构造函数。
原型链
原型对象方法中this指向实例对象,一般情况下,谁调用方法,this就指向谁。
原型对象的作用
扩张内置对象的方法
<script>
// 原型对象的应用 扩展内置对象方法
Array.prototype.sum = function() {
var sum = 0;
for (var i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
};
//不能直接赋值给原型对象,否则会覆盖原型对象中的其他方法
// Array.prototype = {
// sum: function() {
// var sum = 0;
// for (var i = 0; i < this.length; i++) {
// sum += this[i];
// }
// return sum;
// }
// }
var arr = [1, 2, 3];
console.log(arr.sum());
console.log(Array.prototype);
var arr1 = new Array(11, 22, 33);
console.log(arr1.sum());
</script>
call()方法
作用:调用函数和改变函数的this指向。
<script>
// call 方法
function fn(x, y) {
console.log('我想喝手磨咖啡');
console.log(this);
console.log(x + y);
}
var o = {
name: 'andy'
};
// fn();
// 1. call() 可以调用函数
// fn.call();
// 2. call() 可以改变这个函数的this指向 此时这个函数的this 就指向了o这个对象
fn.call(o, 1, 2);
</script>
继承特性
构造函数与原型对象组合继承
<script>
// 借用父构造函数继承属性
// 1. 父构造函数
function Father(uname, age) {
// this 指向父构造函数的对象实例
this.uname = uname;
this.age = age;
}
// 2 .子构造函数
function Son(uname, age, score) {
// this 指向子构造函数的对象实例
Father.call(this, uname, age);
this.score = score;
}
var son = new Son('刘德华', 18, 100);
console.log(son);
</script>
<script>
// 借用父构造函数继承属性
// 1. 父构造函数
function Father(uname, age) {
// this 指向父构造函数的对象实例
this.uname = uname;
this.age = age;
}
Father.prototype.money = function() {
console.log(100000);
};
// 2 .子构造函数
function Son(uname, age, score) {
// this 指向子构造函数的对象实例
Father.call(this, uname, age);
this.score = score;
}
// Son.prototype = Father.prototype; 这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
Son.prototype = new Father();
// 如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数
Son.prototype.constructor = Son;
// 这个是子构造函数专门的方法
Son.prototype.exam = function() {
console.log('孩子要考试');
}
var son = new Son('刘德华', 18, 100);
console.log(son);
console.log(Father.prototype);
console.log(Son.prototype.constructor);
</script>
解释代码不能直接对原型对象赋值,先实例化一个实例对象,再对实例化对象的原型函数进行赋值