js之继承

在传统的面向对象编程语言中,都有类的概念,类可以从父类继承属性和方法。但是,在ECMAScript5规范中没有类的概念(ECMAScript6规范开始引入),但是继承可以发生在对象之间。

一、原型对象的继承

原型对象继承是JavaScript原生的(默认的)继承方式。

默认情况下,所有对象(包括通过自定义构造函数创建的对象)都间接或直接继承自Object.prototype原型对象。也就是说,Object.prototype原型对象中的属性和方法会被所有对象继承。

(1)直接继承

// var obj = new Object();
var obj = {};
console.log(obj);
// obj的原型对象就是Object.prototype
console.log(Object.getPrototypeOf(obj) === Object.prototype);  // true

(2)间接继承

var arr = new Array(1,2);

console.log(arr);

// 通过new Array()创建出对象arr,所以arr的原型对象就是Array.prototype
console.log(Object.getPrototypeOf(arr) === Array.prototype);  // true

// Array本身也是对象,所以Array.prototype的原型对象就是Object.prototype

console.log(Object.getPrototypeOf(Array.prototype) === Object.prototype);  // true


// 原型链:arr.__proto__ ---> Array.prototype.__proto__ ---> Object.prototype

 Object.prototype上所有属性和方法:

  • hasOwnProperty:检测对象自己的属性列表中是否包含某个属性,如果包含返回true,否则返回false
  • isPrototypeOf :检测某个对象是否是另一个对象的原型对象
  • propertyIsEnumerable : 检测对象中某个属性是否可枚举
  • toLocaleString:  返回符合国情的字符串表示形式(如:打印时间对象时,返回的字符串)
  • toString:  返回对象的字符串表示形式
  • valueOf:  使用 valueOf 方法获取对象的原始值(如:创建时间对象后获取毫秒值)

 

二、对象的继承

var obj = {
    fname: '赵四'
}

var obj2 = new Object();
obj2.fname = '刘能';

console.log(Object.prototype.isPrototypeOf(obj));  // true
console.log(Object.prototype.isPrototypeOf(obj2));  // true

使用Object.create()可以以某个对象为原型创建对象,同时还可以定义属性的特性 

var obj = {
    fname: '赵四',
    get getFname() {
        return this.fname;
    }
}

// 使用Object.create()可以以某个对象为原型创建对象,同时还可以定义属性的特性

var obj2 = Object.create(obj, {
    'fname': {
        enumerable: true,
        configurable: false,
        writable: true,
        value: '刘能'
    },
    'age': {
        enumerable: true,
        configurable: false,
        writable: true,
        value: 20
    }
});
console.log(obj2);
console.log(obj2.getFname);  // 刘能,从obj继承来的访问器属性,沿着原型链查找
console.log(Object.getPrototypeOf(obj2) === obj);  // true

 三、构造函数的继承

// 矩形
function Rectangle(width, height){
    this.width = width;
    this.height = height;
}

// 添加共享属性
Object.defineProperties(Rectangle.prototype, {
    getArea: {
        enumerable: false,
        configurable: false,
        writable: false,
        value: function(){ 
            return '矩形的面积是:' + (this.width * this.height);
        }
    }
})

// 正方形
function Square(size){
    this.width = size;
    this.height = size;
}

// 第一种方式
// Square.prototype.__proto__ = Rectangle.prototype;
// var square = new Square();
// console.log(Object.getPrototypeOf(square) === Square.prototype);  // true


// 第二种方式
Square.prototype = Object.create(Rectangle.prototype, {
    constructor: {
        enumerable: false,
        configurable: false,
        writable: false,
        value: Square
    }
});

var square = new Square(20);
console.log(square.getArea().replace('矩形', '正方形'));  // 正方形的面积是:400

console.log(square.__proto__ === Square.prototype);  // true
console.log(Square.prototype.__proto__ === Rectangle.prototype);  // true

覆盖父类的方法 

// 矩形
function Rectangle(width, height){
    this.width = width;
    this.height = height;
}

// 添加共享属性
Object.defineProperties(Rectangle.prototype, {
    getArea: {
        enumerable: false,
        configurable: false,
        writable: false,
        value: function(){ 
            return '矩形的面积是:' + (this.width * this.height);
        }
    }
})

// 正方形
function Square(size){
    this.width = size;
    this.height = size;
}

Square.prototype = Object.create(Rectangle.prototype, {
    constructor: {
        enumerable: false,
        configurable: false,
        writable: false,
        value: Square
    },
    // 覆盖父类的方法
    getArea: {
        enumerable: false,
        configurable: false,
        writable: false,
        value: function(){ 
            return '矩形的面积是:' + (this.width * this.height);
        }
    }
});

var square = new Square(20);
console.log(square.getArea().replace('矩形', '正方形'));  // 正方形的面积是:400

console.log(square.__proto__ === Square.prototype);  // true
console.log(Square.prototype.__proto__ === Rectangle.prototype);  // true

借用父类的方法:

// 矩形
function Rectangle(width, height){
    this.width = width;
    this.height = height;
}

// 添加共享属性
Object.defineProperties(Rectangle.prototype, {
    getArea: {
        enumerable: false,
        configurable: false,
        writable: false,
        value: function(){ 
            console.log(this);
            
            return '矩形的面积是:' + (this.width * this.height);
        }
    }
})

// 正方形
function Square(size){
    this.width = size;
    this.height = size;
}

Square.prototype = Object.create(Rectangle.prototype, {
    constructor: {
        enumerable: false,
        configurable: false,
        writable: false,
        value: Square
    },
    getArea: {
        enumerable: false,
        configurable: false,
        writable: false,
        value: function(){
            // 调用父类的方法
            return Rectangle.prototype.getArea.call(this).replace('矩形', '正方形');
        }
    }
});

var square = new Square(20);
console.log(square.getArea());  // 正方形的面积是:400

console.log(square.__proto__ === Square.prototype);  // true
console.log(Square.prototype.__proto__ === Rectangle.prototype);  // true

调用父类的构造函数: 

// 矩形
function Rectangle(width, height){
    this.width = width;
    this.height = height;
}

// 添加共享属性
Object.defineProperties(Rectangle.prototype, {
    getArea: {
        enumerable: false,
        configurable: false,
        writable: false,
        value: function(){ 
            console.log(this);
            
            return '矩形的面积是:' + (this.width * this.height);
        }
    }
})

// 正方形
function Square(size){
    // this.width = size;
    // this.height = size;

    Rectangle.call(this, size, size);
}

Square.prototype = Object.create(Rectangle.prototype, {
    constructor: {
        enumerable: false,
        configurable: false,
        writable: false,
        value: Square
    }
});

var square = new Square(20);
console.log(square.getArea().replace('矩形', '正方形'));  // 正方形的面积是:400

console.log(square.__proto__ === Square.prototype);  // true
console.log(Square.prototype.__proto__ === Rectangle.prototype);  // true

arr.__proto__ ---> Array.prototyp

e.__proto__ ---> Object.prototype

arr.__proto__ ---> Array.prototype.__proto__ ---> Object.prototy 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值