js学问梳理4.继续的形式探讨

写在前面

注:这个系列是本人对js学问的一些梳理,个中不少内容来自书本:Javascript高等程序设计第三版和JavaScript威望指南第六版,谢谢它们的作者和译者。有发明什么题目的,迎接留言指出。

1.原型链

将原型链作为完成继续的要领,基本思想就是应用原型让一个援用范例继续另一个援用范例的属性和要领:

function SuperType() {
    this.property = true;
}
SuperType.prototype.getSuperValue = function () {
    return this.property;
}
function SubType() {
    this.subproperty = false;
}
//继续了SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function () {
    return this.subproperty;
}
var instance = new SubType();
console.log(instance.getSuperValue());//true

原型链完成继续的题目:①题目来自包括援用范例值的原型,由于本来的实例属性变成如今的原型属性,会被同享,②在建立子类时,不能向超范例的组织函数中通报参数。

function SuperType() {
    this.colors = ["red","blue","green"];
}
function SubType() {}
//继续了SuperType
SubType.prototype = new SuperType();

var instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors);//["red", "blue", "green", "black"]

var instance2 = new SubType();
console.log(instance2.colors);//["red", "blue", "green", "black"]

2.借用组织函数

等于在子范例组织函数的内部挪用超范例组织函数(还能够通报参数):

function SuperType(name) {
    this.name = name;
    this.colors = ["red","blue","green"];
}
function SubType() {
    SuperType.call(this,'jaychou');
}
var instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors);//["red", "blue", "green", "black"]
console.log(instance1.name);//jaychou

var instance2 = new SubType();
console.log(instance2.colors);//["red", "blue", "green"]
console.log(instance2.name);//jaychou

借用组织函数的题目:要领都在组织函数中定义,没有举行函数复用。而且在超范例的原型中定义的要领,对子范例而言也是不可见的,效果一切范例都只能运用组织函数形式。斟酌到这些题目,借用组织函数的手艺也是很少零丁运用的。

3.组合继续

即运用原型链完成对原型属性和要领的继续,而经由历程借用组织函数来完成对实例属性的继续。既经由历程在原型上定义要领完成了函数复用,又能够保证每一个实例都有它自己的属性:

function SuperType(name) {
    this.name = name;
    this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function () {
    console.log(this.name);
}

function SubType(name,age) {
    //继续实例属性
    SuperType.call(this,name);

    this.age = age;
}
//继续原型中的要领
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function () {
    console.log(this.age);
}

var instance1 = new SubType('jaychou',34);
instance1.colors.push("black");
console.log(instance1.colors);//["red", "blue", "green", "black"]
instance1.sayName();//jaychou
instance1.sayAge();//34

var instance2 = new SubType('xiaoming',15);
console.log(instance2.colors);//["red", "blue", "green"]
instance2.sayName();//xiaoming
instance2.sayAge();//15

4.原型式继续

没有运用严厉意义上的组织函数,借助原型能够基于已有的对象建立新对象的特性。同时还没必要因而建立自定义范例:

function inherit(p) {
    if(p==null) throw TypeError();
    if(Object.create) return Object.create(p);
    var t = typeof p;
    if(t !== "object" && t !== "funtion") throw TypeError();
    function f() {};
    f.prototype = p;
    return new f();
}

优点:简朴直接轻易,只是简朴地想一个对象与另一个对象坚持相似的情况下,原型式继续是很不错的做法。注重点:包括援用范例值的属性一直都邑同享响应的值,就像运用原型形式一样,如:

var person = {
    name:'jaychou',
    friends:[1,2]
}
var anotherP = inherit(person);
anotherP.friends.push(3);
console.log(person.friends);//[1, 2, 3]
anotherP.name = "xiaoming";
console.log(anotherP.name);//xiaoming
console.log(person.name);//jaychou

所以从本质上讲,原型式继续就是对传过来的对象执行了一次浅复制。

5.寄生式继续

即建立一个仅用于封装继续历程的函数,该函数在内部以某种体式格局来加强对象,末了返回对象(接上):

function createAnother(original) {
    var clone = inherit(original);
    clone.sayHi = function () {
        console.log("hi");
    }
    return clone;
}
var person = {
    name:'jaychou',
    friends:[1,2]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();

在例子里给传进来的对象增加了要领sayHi,加强了对象。在重要斟酌对象而不是自定义范例和组织函数的情况下,这个形式也不错。瑕玷:不能做到函数复用而降低效率了

6.寄生组合式继续

组合继续的题目就是挪用了两次超范例组织函数:一次是在建立子范例原型的时刻,另一次是在子范例组织函数内部。解决方案就是:没必要为了指定子范例的原型而挪用超范例的组织函数,我们所须要的不过就是超范例原型的一个副本罢了。本质上,就是运用寄生式继续来继续超范例的原型,然后再将效果指定给子范例的原型:

//寄生组合式继续
function inheritPrototype(subType, superType) {
    var prototype = inherit(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}
function SuperType(name) {
    this.name = name;
    this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function () {
    console.log(this.name);
}
function SubType(name,age) {
    //借用超范例的组织函数继续了超范例的实例属性
    SuperType.call(this,name);
    this.age = age;
}
//寄生式继续了超范例的原型要领
inheritPrototype(SubType,SuperType);

SubType.prototype.sayAge = function () {
    console.log(this.age);
}

var instance1 = new SubType("jaychou",34);
instance1.sayName();//jaychou
instance1.sayAge();//34

console.log(SuperType.prototype.isPrototypeOf(instance1));//true
console.log(instance1 instanceof SuperType);//true

优点:①只挪用了一处SuperType组织函数,②避免了在SubType.prototype上面建立没必要要的、过剩的属性。综上,寄生组合式继续是继续的最理想体式格局。

    原文作者:QCJay
    原文地址: https://segmentfault.com/a/1190000016072122
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞