Javascript学习笔记之函数篇(五) : 构造函数


Posted in Javascript onNovember 23, 2014

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

上面的例子可能在某些场景下也可以运行,但由于 Javascript 中 this 的工作机制,这里 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 可能比较容易产生错误,但这并不能成为放弃使用原型链的原因。至于最后采取哪种方式,这需要根据应用的需求而定。最好的方式就是选择一种风格并坚持下去。

简单的说构造函数就是初始化一个实例对象,对象的prototype属性是继承一个实例对象。

Javascript 相关文章推荐
我也种棵OO树JXTree[js+css+xml]
Apr 02 Javascript
jquery ajax中使用jsonp的限制解决方法
Nov 22 Javascript
js复制网页内容并兼容各主流浏览器的代码
Dec 17 Javascript
jQuery使用andSelf()来包含之前的选择集
May 19 Javascript
jQuery 获取兄弟元素的几种不错方法
May 23 Javascript
javascript实现控制的多级下拉菜单
Jul 05 Javascript
jQuery简单实现两级下拉菜单效果代码
Sep 15 Javascript
简单讲解jQuery中的子元素过滤选择器
Apr 18 Javascript
Vue2学习笔记之请求数据交互vue-resource
Feb 23 Javascript
jQuery上传插件webupload使用方法
Aug 01 jQuery
JS实现问卷星自动填问卷脚本并在两秒自动提交功能
Jun 17 Javascript
JavaScript自动生成 年月范围 选择功能完整示例【基于jQuery插件】
Sep 03 jQuery
Javascript学习笔记之函数篇(四):arguments 对象
Nov 23 #Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
Nov 23 #Javascript
js实例属性和原型属性示例详解
Nov 23 #Javascript
JS常用函数使用指南
Nov 23 #Javascript
浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用
Nov 23 #Javascript
理解jQuery stop()方法
Nov 21 #Javascript
JS中三目运算符和if else的区别分析与示例
Nov 21 #Javascript
You might like
PHP的password_hash()使用实例
2014/03/17 PHP
PHP中批量生成静态html(命令行下运行PHP)
2014/04/19 PHP
PHP获取时间排除周六、周日的两个方法
2014/06/30 PHP
PHP查看当前变量类型的方法
2015/07/31 PHP
Smarty高级应用之缓存操作技巧分析
2016/05/14 PHP
图片之间的切换
2006/06/26 Javascript
window.dialogArguments 使用说明
2011/04/11 Javascript
javascript是怎么继承的介绍
2012/01/05 Javascript
js的onload事件及初始化按钮事件示例代码
2013/09/25 Javascript
ajax与302响应代码测试
2013/10/23 Javascript
jQuery验证插件 Validate详解
2014/11/20 Javascript
js实现鼠标感应向下滑动隐藏菜单的方法
2015/02/20 Javascript
基于js实现投票的实例代码
2015/08/04 Javascript
jquery.validate提示错误信息位置方法
2016/01/22 Javascript
jQuery如何解决IE输入框不能输入的问题
2016/10/08 Javascript
jQuery轻松实现无缝轮播效果
2017/03/22 jQuery
Angular移动端页面input无法输入的解决方法
2017/11/14 Javascript
python使用sorted函数对列表进行排序的方法
2015/04/04 Python
python使用urllib2提交http post请求的方法
2015/05/26 Python
通过数据库向Django模型添加字段的示例
2015/07/21 Python
Pycharm编辑器技巧之自动导入模块详解
2017/07/18 Python
Python 通配符删除文件的实例
2018/04/24 Python
Python实现使用卷积提取图片轮廓功能示例
2018/05/12 Python
python利用Tesseract识别验证码的方法示例
2019/01/21 Python
selenium+python截图不成功的解决方法
2019/01/30 Python
关于sys.stdout和print的区别详解
2019/12/05 Python
美国摩托车头盔、零件、齿轮及配件商店:Cycle Gear
2019/06/12 全球购物
DJI全球:DJI Global
2021/03/15 全球购物
简历中的自我评价怎么写
2014/01/29 职场文书
情侣吵架检讨书
2014/02/05 职场文书
学徒工职责
2014/03/06 职场文书
安装工程师岗位职责
2015/02/13 职场文书
商务代表岗位职责
2015/02/15 职场文书
同学聚会致辞集锦
2015/07/28 职场文书
2016年情人节问候语
2015/11/11 职场文书
Java Optional<Foo>转换成List<Bar>的实例方法
2021/06/20 Java/Android