JS 原始型别的包裹物件与原型的关联 DAY67

var b = new String('abcdef'); // 这里 String 为建构函式
console.log(b);
console.dir(String); // 也有 prototype 此属性
String.prototype.lastText = function(){
    return this[this.length - 1];
}
console.log(b.lastText()); // f
Number.prototype.secondpower = function(){
    return this * this;
}
var num = 5;
console.log(num.secondpower()); // 25

日期

var date = new Date();
console.log(date);
console.dir(Date);
Date.prototype.getFullDate = function(){
    var day = this.getDate();
    var month = this.getMonth()+1;
    var year = this.getFullYear();
    var today = year + '/' + month + '/' + day;
    return today;
}
console.log(date.getFullDate());

使用 Object.create 建立多层继承

我们要如何在原型链上新增一个层级呢??
我们上一篇有提到

function Dog(nickname , color , size){
    this.nickname = nickname;
    this.color = color;
    this.size = size;
}
var black = new Dog('小黑','黑色','大'); 
console.log(black);
// Object -> Dog -> black(实体)
// Object -> Animal -> Dog -> black(实体)
// Object -> Animal -> Cat -> black(实体)

这里我们先来介绍 Object.create
Object.create 可以把 物件 作为原型使用

var black = {
    nickname: '小黑',
    color: '黑色',
    size: '大',
    bark: function(){
        console.log(this.nickname + '吠叫');
    }
}
var white = Object.create(black);
console.log(white); // {}
console.log(white.nickname); // 小黑
white.nickname = '小白';
console.log(white.nickname); // 小白
// 所以在不改变属性的情况下
// white 的值都可以 以 black 作为预设值

这里在举一个完整例子

function Animal(family){
    this.kingdom = '动物界';
    this.family = family || '人科';
}
Animal.prototype.move = function(){
    console.log( this.nickname + '移动' );
}
function Dog(nickname,color,size){
    this.nickname = nickname;
    this.color = color || '白色';
    this.size = size || '小';
}
Dog.prototype = Object.create(Animal.prototype); // Dog的原型继承Animal的原型
Dog.prototype.bark = function(){
    console.log(this.nickname + '吠叫');
}
var black = new Dog('小黑','黑色','大');
console.log(black);
console.log(black.family); // undefined
black.bark();
black.move();

不过会发现我们的科别与动物界都没有显示(undefined)
是因为 Dog 只有继承 Animal 的原型
并没有继承 Animal 的建构函式
所以改成这样

function Animal(family){
    this.kingdom = '动物界';
    this.family = family || '人科';
}
Animal.prototype.move = function(){
    console.log( this.nickname + '移动' );
}
function Dog(nickname,color,size){
    Animal.call(this,'犬科');
    this.nickname = nickname;
    this.color = color || '白色';
    this.size = size || '小';
}
Dog.prototype = Object.create(Animal.prototype); // Dog的原型继承Animal的原型
Dog.prototype.bark = function(){
    console.log(this.nickname + '吠叫');
}
var black = new Dog('小黑','黑色','大');
console.log(black);
console.log(black.family); // undefined
black.bark();
black.move();

不过这里还有一个小问题
black 目前的 constructor 为 Animal
这里简单说明一下 constructor
constructor: 使用建构函式产生一个物件,则物件内的constructor会指向原本的建构函式
所以 black 的 constructor 应该为 Dog
那为什麽它原本的 constructor 是 Animal呢??
因为

Dog.prototype = Object.create(Animal.prototype);

这行覆盖掉它了
所以必须把它补回来

function Animal(family){
    this.kingdom = '动物界';
    this.family = family || '人科';
}
Animal.prototype.move = function(){
    console.log( this.nickname + '移动' );
}
function Dog(nickname,color,size){
    Animal.call(this,'犬科');
    this.nickname = nickname;
    this.color = color || '白色';
    this.size = size || '小';
}
Dog.prototype = Object.create(Animal.prototype); // Dog的原型继承Animal的原型
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function(){
    console.log(this.nickname + '吠叫');
}
var black = new Dog('小黑','黑色','大');
console.log(black);
console.log(black.family); // undefined
black.bark();
black.move();

console.log(black.constructor); // Dog 的建构函式

这里我们在加上猫的物种

function Animal(family){
    this.kingdom = '动物界';
    this.family = family || '人科';
}
Animal.prototype.move = function(){
    console.log( this.nickname + '移动' );
}
function Dog(nickname,color,size){
    Animal.call(this,'犬科');
    this.nickname = nickname;
    this.color = color || '白色';
    this.size = size || '小';
}
Dog.prototype = Object.create(Animal.prototype); // Dog的原型继承Animal的原型
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function(){
    console.log(this.nickname + '吠叫');
}
var black = new Dog('小黑','黑色','大');
console.log(black);
console.log(black.family); // undefined
black.bark();
black.move();

function Cat(nickname,color,size){
    Animal.call(this,'猫科');
    this.nickname = nickname;
    this.color = color;
    this.size = size;
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
Cat.prototype.meow = function(){
    console.log(this.nickname + '喵喵叫');
}
var kitty = new Cat('凯蒂','白色','大');
kitty.meow();
kitty.move();

那今天的介绍就到这里
若有任何问题 或 内容有误
都可以跟我说唷/images/emoticon/emoticon41.gif


<<:  前端工程学习日记第12天

>>:  [Angular] Forms - Introduction to form in Angular

D28: 工程师太师了: 第14.5话

工程师太师了: 第14.5话 杂记: 伫列(queue)是一种利用FIFO(First In Fir...

Day 11 彩色黑白渐层照片

彩色黑白渐层照片 教学原文参考:彩色黑白渐层照片 这篇文章会介绍使用 GIMP 的图层混合模式、渐层...

聊招募前,先问问你了解自己吗?

成为公司的一份子大都是经由招募流程而加入的,但某一天团队需要扩大或是人手不足,而你刚好有机会可以参与...

前端工程学习日记第三天

小技巧:ul>li*3 打出来 可以用emmet快速做出 昨日疑问:我的HTML为何没有快速工...

Golang - 使用docker部署专案

之前就有做过这件事情 当时搞定了之後想说,简单吗~~~就是搞个Dockerfile而已 结果好一阵子...