资讯专栏INFORMATION COLUMN

js继承实现之Object.create

Joonas / 2503人阅读

摘要:是对象的一个实例,并且的。可以自己定义它的属性,可写可配可枚举,均可自己定义,实现一条龙自助服务。这种方式比较适合父类为同级别,子类只要拥有相同的属性和方法即可的情况。如有异议处,欢迎大家指出来,一起探讨。

同事前几天去面试,回来同步了一下面试题库,其中一道题就是”new和Object.create的区别”。听到这个题目,我的第一个反映是 , what?( ⸝⸝⸝°_°⸝⸝⸝ ), Object.create这个东东我没有用过,怎么回答。为了避免无法给出response的尴尬,老夫抓紧一切时间开始在console里演示着。

-> demo <-

function Person(name, sex) {
   this.name = name;
   this.sex = sex;
}
Person.prototype.getInfo = function() {
   console.log("getInfo: [name:" + this.name + ", sex:" + this.sex + "]");
}
var a = new Person("jojo", "femal");
var b = Object.create(Person.prototype);

-> 分析 <-

赤裸裸的结果,a就是对象Person的实例,a.__proto__ === Person.prototype。what about b ? b是对象F的一个实例,并且b.__proto__ === Person.prototype的。

这个F到底是个啥呢? 好了,又到了copy-paste时间了,参考了https://developer.mozilla.org... 其实现的polyfill方法:

if (typeof Object.create !== "function") {
    //此方法未考虑create的第二个参数的实现
    Object.create = function (proto, propertiesObject) {
        if (typeof proto !== "object" && typeof proto !== "function") {
            throw new TypeError("Object prototype may only be an Object: " + proto);
        } else if (proto === null) {
            throw new Error("This browser"s implementation of Object.create is a shim and doesn"t support "null" as the first argument.");
        }

        if (typeof propertiesObject != "undefined") throw new Error("This browser"s implementation of Object.create is a shim and doesn"t support a second argument.");
        //实现一个隐藏函数
        function F() {}
        //函数的原型设置为参数传进来的原型
        F.prototype = proto;
        // 返回一个F函数的实例,即此实例的__proto__指向为参数proto
        return new F();
    };
}

好吧,既然都看了polyfill了,就知道Object.create到底是干啥的了,它就是生成了一个实例,这个实例的原型由我来指定,但是它的构造函数F被隐藏了。那下面我们来验证一下是不是这个逻辑。

通过Object.create()生成的实例怎么才能有自己的属性呢,别怕,我们看一下它完成的面目是怎样的,撒花,揭幕~~Object.create(proto, [propertiesObject]), 人家是有第二个参数滴。可以自己定义它的属性,可写、可配、可枚举,均可自己定义,实现一条龙自助服务。

var b = Object.create(Person.prototype, {
    name: {
        value: "coco",
        writable: true,
        configurable: true,
        enumerable: true,
    },
    sex: {
        enumerable: true,
        get: function(){ return "hello sex"},
        set: function(val){console.log("set value:" + val)}
    }
})

-> 更进一步 <-

说了这么多,那Object.create的应用价值到底是什么呢? 看一下本文标题就知道了,当然说的是继承了,操刀试一下。

function Student(name, sex, age) {
    Person.call(this, name, sex);
    this.age = age;
}
//原型链拼接
Student.prototype = Object.create(Person.prototype);
//构造函数弯了,纠正
Student.prototype.constructor = Student;
Student.prototype.getInfo = function() {
    console.log("getInfo: [name:" + this.name + ", sex:" + this.sex + ", age:" +this.age + "].");
}
    
var s = new Student("coco", "femal", 25);

s是Student的实例,Person.prototype在s的原型链上,并且这个F实例的constructor又指回了Student。
既然说到了这里,那如果想要一个对象继承多个类怎么办呢?在上面的代码基础上使用mixin加工下就可啦。

//再创建一个基类
function Animal(age) {
 this.age = age;
}
Animal.prototype.say = function(language) { 
    console.log("you say " + language);
}

function Student(name, sex, age) {
    Person.call(this, name, sex);
    Animal.call(this, age);
}
//原型链拼接
Student.prototype = Object.create(Person.prototype);
Object.assign(Student.prototype, Animal.prototype);
Student.prototype.constructor = Student;
Student.prototype.getInfo = function() {
    console.log("getInfo: [name:" + this.name + ", sex:" + this.sex + ", age:" +this.age + "].");
};
var s = new Student("coco", "femal", 25);

s的原型仍是一个F实例,其原型指向了Person,但是这个F实例上mixin了Animal的方法。但是原型链上并没有Animal什么事,通过instanceof可以验证这一点。这种方式比较适合父类为同级别,子类只要拥有相同的属性和方法即可的情况。

如有异议处,欢迎大家指出来,一起探讨。学习费脑掉了好多头皮屑,不过今天又可以碎个觉了。

∧__∧
( ●ω●)
|つ/(___
/└-(____/bug>>>bug>>bug>bug
 ̄ ̄ ̄ ̄ ̄ ̄

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94589.html

相关文章

  • JS面向对象的程序设计继承实现-原型式继承和寄生式继承

    摘要:通过新增方法规范了原型式继承。适用场景在没有必要兴师动众地创建构造函数,而只想让一个对象与另外一个对象保持类似的情况下,原型式继承是完全可以胜任的。在主要考虑对象而不是自定义类型和构造函数的情况下,寄生式继承也是一种有用的模式。 --前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。如有纰漏或错误,会非常感...

    lewinlee 评论0 收藏0
  • 深入理解 js 继承与原型链

    摘要:原型链与继承当谈到继承时,只有一种结构对象。如果对该图不怎么理解,不要着急,继续往下看基于原型链的继承对象是动态的属性包指其自己的属性。当使用操作符来作用这个函数时,它就可以被称为构造方法构造函数。 原型链与继承 当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object )都有一个私有属性(称之为proto)指向它的原型对象(prototype)。该原型对象也...

    xingqiba 评论0 收藏0
  • 揭秘babel的魔法class继承的处理2

    摘要:并且用验证了中一系列的实质就是魔法糖的本质。抽丝剥茧我们首先看的编译结果这是一个自执行函数,它接受一个参数就是他要继承的父类,返回一个构造函数。 如果你已经看过第一篇揭秘babel的魔法之class魔法处理,这篇将会是一个延伸;如果你还没看过,并且也不想现在就去读一下,单独看这篇也没有关系,并不存在理解上的障碍。 上一篇针对Babel对ES6里面基础class的编译进行了分析。这一篇将...

    BlackHole1 评论0 收藏0
  • JavaScript深入各种继承

    摘要:通常有这两种继承方式接口继承和实现继承。理解继承的工作是通过调用函数实现的,所以是寄生,将继承工作寄托给别人做,自己只是做增强工作。适用基于某个对象或某些信息来创建对象,而不考虑自定义类型和构造函数。 一、继承的概念 继承,是面向对象语言的一个重要概念。通常有这两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。 《JS高程》里提到:由于函数没有签名,...

    tomlingtm 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<