构造函数

68 阅读2分钟

扩展内置对象

// 原型对象的应用,扩展内置对象方法
// 在构造函数中,里面的this指向的是对象实例
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', arr.sum());  // 6

let arr1 = new Array(11, 22, 33);
console.log('arr1', arr1.sum());  // 66

继承

ES6之前并没有给我们提供 extends 继承, 我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承。

call()

调用这个函数,并且修改函数运行时的 this 指向

fun.call(thisArg, arg1, arg2, ...)
  • thisArg:当前调用函数 this 的指向对象
  • arg1,arg2:传递的其他参数
// call方法
function fn() {
  console.log('我想喝手磨咖啡');
  console.log(this)
}
// 可以直接正常调用,也可以通过call()调用函数
// fn();  // 我想喝手磨咖啡  this指向window
// fn.call();  // 我想喝手磨咖啡  this指向window

function fn2(x: number, y: number) {
  console.log('我想喝手磨咖啡');
  console.log(this)
  console.log(x + y);
}
let obj = {
  name: '张三'
}
// call()可以改变这个函数的this指向 此时这个函数的this 就指向了obj这个对象
fn2.call(obj, 1, 2); // this指向了obj对象{name: '张三'}   3

利用原型对象实现方法的继承

// 借用父构造函数继承属性
// 1. 父构造函数
function Father(uname, age) {
  this.uname = uname;
  this.age = age;
}
Father.prototype.money = function() {
  console.log(1000000)
}
// 2. 子构造函数
function Son(uname, age, score) {
  // this 指向子构造函数的对象实例
  Father.call(this, uname, age);
  this.score = score;
}

// 错误的继承方法
// 方法的继承(子构造函数继承父构造函数的方法)
// Son.prototype = Father.prototype;  这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化。
// 比如子原型对象独有的方法exam也会被父原型对象继承

// 正确的继承方法 创建一个父原型的实例赋值给子原型对象
Son.prototype = new Father();
// 如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数
Son.prototype.constructor = Son;

// 这个是子构造函数专门的方法(不需要父构造函数继承)
Son.prototype.exam = function() {
  console.log('我要考试')
}
var son = new Son('刘德华', 18, 100);
console.log('son', son);
console.log('Father.prototype', Father.prototype);

类的本质

  1. class的本质其实还是一个函数,我们也可以简单的认为 类就是 构造函数的另外一种写法