资讯专栏INFORMATION COLUMN

细说 Javascript 函数篇(五) : 构造函数

sPeng / 2882人阅读

Javascript 中的构造函数与其他语言相比也是不同的。任何通过关键字 new 调用的函数都可以当做构造函数。
在构造函数体内,this 指向新创建的对象。如果构造函数体内没有显示的 return 表达式,那么我们就默认返回 this,也就是新建的对象。

function Foo() {
    this.bla = 1;
}

Foo.prototype.test = function() {
    console.log(this.bla);
};

var test = new Foo();

上面的代码将 Foo 作为构造函数进行调用,并将新建对象的原型(__proto__)指向了 Foo.prototype
如果我们在构造函数内定义返回的 return 表达式,构造函数就会返回整个表达式,但这个返回表达式必须为一个对象。

function Bar() {
    return 2;
}
new Bar(); // a new object

function Test() {
    this.value = 2;

    return {
        foo: 1
    };
}
new Test(); // the returned object

如果 new 被省略,那么函数将不能返回一个新的对象。

function Foo() {
    this.bla = 1; // gets set on the global object
}
Foo(); // undefined

上面的例子可能在某些场景下也可以运行,但由于 Javascriptthis 的工作机制,这里 this 将指向全局对象。

工厂模式

为了能够不使用关键字 new,构造函数将不得不显示返回一个值。

function Bar() {
    var value = 1;
    return {
        method: function() {
            return value;
        }
    }
}
Bar.prototype = {
    foo: function() {}
};

new Bar();
Bar();

上例中使不使用 new 来调用函数 Bar 达到的效果是一样的,将会返回一个新建的包含 method 方法的对象,这里实际上就是一个闭包。
这里需要注意一点,new Bar() 将不会返回 Bar.prototype,而是在 return 表达式内函数 method 的原型对象。
上例中,使用 new 与否在功能上是无差异的。

通过工厂模式创建新的对象

我们经常被提醒不要使用 new,因为一旦忘记了它的使用将导致错误。
为了创建一个对象,我们更愿意使用工厂模式并在工厂模式内构造一个新的对象。

function Foo() {
    var obj = {};
    obj.value = "blub";

    var private = 2;
    obj.someMethod = function(value) {
        this.value = value;
    }

    obj.getPrivate = function() {
        return private;
    }
    return obj;
}

尽管上例代码比使用 new 时更不容易出错,而且在使用私有变量时将更加方便,但同时也有一些不好的地方:

因为不能共享原型对象,所以需要更多的内存。

为了实现继承,工厂模式需要拷贝另一个对象的所有方法或者将其作为新对象的原型。

放弃原型链只是为了避免使用 new,这似乎与 Javascript 语言的精神相悖。

总结

尽管使用 new 可能比较容易产生错误,但这并不能成为放弃使用原型链的原因。至于最后采取哪种方式,这需要根据应用的需求而定。最好的方式就是选择一种风格并坚持下去。

参考

http://bonsaiden.github.io/JavaScript-Garden/#function.constructors

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

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

相关文章

  • 细说 Javascript 函数(二) : this 的工作机制

    摘要:与其他编程语言相比,对的使用是一套完全不同的机制。在五种情况下的值是各有不同的。调用一个函数时在这里,同样指向全局对象。此时在函数内,指向新建的对象。尽管,晚绑定初看上去是个不好的决定,但实际上这是原型式继承工作的基础。 与其他编程语言相比,Javascript 对 this 的使用是一套完全不同的机制。this 在五种情况下的值是各有不同的。 全局作用域下 this; 当在全...

    ZoomQuiet 评论0 收藏0
  • 细说 Javascript 对象(二) : 原型对象

    摘要:并没有类继承模型,而是使用原型对象进行原型式继承。我们举例说明原型链查找机制当访问一个对象的属性时,会从对象本身开始往上遍历整个原型链,直到找到对应属性为止。原始类型有以下五种型。此外,试图查找一个不存在属性时将会遍历整个原型链。 Javascript 并没有类继承模型,而是使用原型对象 prototype 进行原型式继承。 尽管人们经常将此看做是 Javascript 的一个缺点,然...

    lansheng228 评论0 收藏0
  • 细说 Javascript 数组(二) : 数组的构造函数和常见操作

    摘要:数组的构造函数由于数组的构造函数在处理参数时的不确定性,因此强烈建议使用符号来创建一个新数组。总结综上所述,我们应该尽量使用来创建新函数,而不是数组的构造函数,这样代码将有更好的可读性。 数组的构造函数 由于数组的构造函数在处理参数时的不确定性,因此强烈建议使用 [] 符号来创建一个新数组。 [1, 2, 3]; // Result: [1, 2, 3] new Array(1, ...

    kaka 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    李昌杰 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    Lyux 评论0 收藏0

发表评论

0条评论

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