JavaScript课程——Day16(扩展原型上的方法、继承)

1、扩展原型上的方法

  1.1、原码中的构造函数

Number String Boolean Function Array Object RegExp Date Error

  1.2、扩展字符串的index()方法

  兼容IE8及以下

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (val, index) {
        index = typeof index === 'undefined' ? 0 : index;
        for (var i = index; i < this.length; i++) {
            if (this[i] === val) {
                return i;
            }
        }
        return -1;
    }
}

var arr = [2, 3, 42, 3, 3, 2];
console.log(arr.indexOf(3)); // 1
console.log(arr.indexOf(3, 2)); // 3

  1.3、扩展字符串的trim方法

  兼容IE8及以下

if (!String.prototype.trim) {
    String.prototype.trim = function () {
        var re = /^s+|s+$/g;
        return this.replace(re, '');
    }
}
var str = '   abc   ';
console.log('(' + str.trim() + ')');

2、继承

子代继承父级,必须得有两方

  2.1、原型链继承

// 父类
function Student() {
    this.job = '学生';
    this.ah = ['打游戏', '处对象', '学习'];
}
Student.prototype.showJob = function () {
    console.log(this.job);
}

// 子类
function SmallStudent(name) {
    this.name = name;
}

// ------------------------------
// 原型链继承:就父类的实例,赋给子类的原型
// 面试中,如何用一句话实现继承?
// 这有很多问题:如果父类有引用类型,会导致一修改,所有新创的的属性都会修改
SmallStudent.prototype = new Student();


var s1 = new SmallStudent('小张');
console.log(s1);
// console.log(s1.name);
// console.log(s1.job);
// console.log(s1.ah);
// s1.showJob();

s1.ah.push('烫头');
console.log(s1.ah);


var s2 = new SmallStudent('小花');
console.log(s2);
console.log(s2.ah);

  2.2、对象冒充继承

// 父类
function Student() {
    this.job = '学生';
    this.ah = ['打游戏', '处对象', '学习'];
}
Student.prototype.showJob = function () {
    console.log(this.job);
}

// 子类
function SmallStudent(name) {
    Student.call(this); // 对象冒充继承:就是在子的构造函数中,调用父的构造函数,然后用call改this指向
    this.name = name;
}

// 对象冒充继承的不足:只能继承属性,不能继承方法

// -----------------------------
var s1 = new SmallStudent('小张');
console.log(s1);
s1.ah.push('烫头');
console.log(s1.ah);
console.log(s1.showJob);

var s2 = new SmallStudent('小花');
console.log(s2);
console.log(s2.ah);

  2.3、组合继承

// 父类
function Student() {
    this.job = '学生';
    this.ah = ['打游戏', '处对象', '学习'];
}
Student.prototype.showJob = function () {
    console.log(this.job);
}

// 子类
function SmallStudent(name) {
    Student.call(this); // 对象冒充
    this.name = name;
}
SmallStudent.prototype = new Student(); // 原型链继承

// 组合继承:对象冒充 + 原型链
// 对象冒充:继承属性
// 原型链:继承方法

// --------------------------------
var s1 = new SmallStudent('小张');

console.log(s1);
s1.showJob();
console.log(s1.constructor); // 本来应该指向子的构造函数,但是却指向了父的构造函数

// 问题:
// 1、constructor指向不对
// 2、同时调用两次父的构造函数
// 3、继承过来的属性,在原型链上会出现两次

  2.4、寄生组合继承

  继承的完美实现

// 父类
function Student() {
    this.job = '学生';
    this.ah = ['打游戏', '处对象', '学习'];
}
Student.prototype.showJob = function () {
    console.log(this.job);
}

// 子类
function SmallStudent(name) {
    Student.call(this); // 继承属性
    this.name = name;
}
inherits(SmallStudent, Student); // 继承方法
// 子类原型上又可以添加方法
SmallStudent.prototype.showName = function () {
    console.log(this.name);
}

// --------------------------
var s1 = new SmallStudent('小张');
console.log(s1);

// ------------------------------------
// 方法的封装
function inherits(Child, Parent) {
    var F = function () { };
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
}

原文地址:https://www.cnblogs.com/miaochaofan/p/14761238.html