Javascript学习笔记8——用JSON做原型


Javascript学习笔记5——类和对象中,我简单地提到了利用JSON去构造一个对象。代码如下:

    <script type="text/javascript">
        var People = {
            name: "kym",
            age: 21,
            SayHello: function () {
                alert("Hello,My name is " + this.name + ".I am " + this.age);
            }
        }
        alert(People.name);
        People.SayHello();
    </script>

但是我们是不能重用这个对象的,我们如何把这个对象作为原型的呢?

首先,在一个JSON对象有一个构造方法是不可能的了,那么我们就做一个简单的“工厂”吧,写一个方法来专门负责创建。

    <script type="text/javascript">
        var People = {
            Create: function (name, age) {
                this.name = name;
                this.age = age;
            },
            SayHello: function () {
                alert("Hello,My name is " + this.name + ".I am " + this.age);
            }
        }
        People.Create("kym", 21);
        People.SayHello();
    </script>

但是通过这个方法我们却发现,我们没有办法用People作为原型,让我们回顾一下:Javascript学习笔记7——原型链的原理 这篇文章,我们想一下这个过程:

var p=new People();==>p.__proto__=People.prototype。于是当我们p.SayHello()的时候就会去People.prototype中去找,结果什么都找不到。

如果可以People.prototype.SayHello=function(){}就可以解决这个问题。但是我们知道,只有function才可以有prototype。

那么我们想想之前的推导公式,怎么样能让p.SayHello()呢?如果可以p.__proto__=People就好了。那么我们想个办法:

既然在new的时候,某个对象的__proto__只能等于某个函数的prototype,我们设置一个函数X,令p.__proto__=X.prototype,我们再令X.prototype=People。这样的关系是这样:

    <script type="text/javascript">
        var People = {
            Create: function (name, age) {
                this.name = name;
                this.age = age;
            },
            SayHello: function () {
                alert("Hello,My name is " + this.name + ".I am " + this.age);
            }
        };
        
        var X = function () { };
        X.prototype = People;
        var p = new X();
        p.Create("kym", 21);
        p.SayHello();
    </script>

这样就相当于用X做了一个中间变量,使得我们可以访问JSON对象的内部属性。但是这样是不是不太优雅呢?我们每次创建一个对象时,都需要来写这样一个辅助的函数。那好,我们就把这个过程封装起来:

var Factory = {
    CreatePeople : function (className,name,age) {
        var temp = function () {
            className.Create(name, age);
        };
        temp.prototype = className;
        var result = new temp();
        return result;
    }
};
var people = Factory.CreatePeople(People,"kym",21);
people.SayHello();

但是这样也有一个缺点,就是每次我增加一个类,就需要向Factory里注册一个新方法,这样是很麻烦的,我在很久以前的 玩转方法:call和apply 中说过关于call和apply的区别,因为这里的参数不固定,我们不可能一一列举,因此我们在这里可以用apply来改善这个方法:

    <script type="text/javascript">
        var People = {
            Create: function (name, age) {
                this.name = name;
                this.age = age;
            },
            SayHello: function () {
                alert("Hello,My name is " + this.name + ".I am " + this.age);
            }
        };

        var Factory = {
            Create: function (className, params) {
                var temp = function () {
                    className.Create.apply(this, params);
                };
                temp.prototype = className;
                var result = new temp();
                return result;
            }
        };
        var people = Factory.Create(People,["kym",21]);
        people.SayHello();
    </script>

这样,一个完整的创建类就诞生了!那么我们每次创建“类”时就都可以用JSON来做了,然后用户每次都统一来调用Factory.Create()就可以了!

优质内容筛选与推荐>>
1、字符串匹配和汉字长度算法
2、仿<赶集生活>client启动动画效果
3、批量修改文件名
4、Android - Error: "java.io.IOException: setDataSource failed.: status=0x80000000"
5、react 中引入 ant-design


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号